线程开始传递的整数本身超出了它应该是什么



我不知道这是怎么回事。我试图通过生成100个线程来不断地访问它来测试一个类的线程安全性,但似乎我的匿名方法参数正在改变自己的值,它们不应该是,我很困惑为什么。由于我不知道发生了什么,我将只发布测试中涉及的所有函数。不知何故,我结束了"线程98"获得参数"num = 100"…这应该是不可能的,我不知道发生了什么改变整数的恶作剧。(在方法"ThreadWriting(int num)"中,您将看到我检查"num"是否等于100的地方,在那里我设置了一个断点来捕获违规线程,并且每次都中断。否则,它会对数组"counts"抛出"IndexOutofRangeException"。我只是想看看我的线程是否通常都能平等地访问它们都试图同时使用的类。

    public delegate void TempDel();
    public TempDel InvokeTest;
    public void TRTest3(Form1 sender)
    {
        InvokeTest = new TempDel(UpdateInvoke);
        Thread t = new Thread(() => ConsoleUpdateTest(sender));
        t.IsBackground = true;
        t.Start();
        POConsole.Instance.MaxLines = 20;
        for(int i = 0; i < 100; i++)
        {
            Thread t2 = new Thread(() => ThreadWriting(i));
            t2.IsBackground = true;
            t2.Name = String.Format("Thread {0}", i);
            t2.Start();
        }
    }
    public ulong[] counts = new ulong[100];
    public void ThreadWriting(int num)
    {
        if(num == 100)
        {
            bool stop = true;
        }
        while (true)
        {
            POConsole.Instance.WriteLine("Hello from Thread " + num);
            counts[num]++;
        }
    }
    public void ConsoleUpdateTest(Form1 sender)
    {
        while(true)
        {
            sender.Invoke(InvokeTest);
            Thread.Sleep(5);
        }
    }

    public void UpdateInvoke()
    {
        QuickTestBox.Text = POConsole.Instance.FullFeed;
    }

我所有的线程都被命名了,正如你所看到的,它们都没有收到"线程100"的名字,所以我不知道其他线程中的一个如何被传递一个参数100或参数可能以某种方式损坏。

显然我的线程安全检查是不是线程安全在某种程度上?

这是一个简单的闭包问题,你不应该使用for循环计数器作为线程参数问题,问题发生在这里,for循环和线程的执行速度不同,所以i的值可以在多个线程中改变:

for(int i = 0; i < 100; i++)
        {
            Thread t2 = new Thread(() => ThreadWriting(i));
            t2.IsBackground = true;
            t2.Name = String.Format("Thread {0}", i);
            t2.Start();
        }

使用以下修改,从循环计数器

创建一个局部变量
for(int i = 0; i < 100; i++)
        {
            int j = i;
            Thread t2 = new Thread(() => ThreadWriting(j));
            t2.IsBackground = true;
            t2.Name = String.Format("Thread {0}", j);
            t2.Start();
        }

相关内容

最新更新