线程启动传递的整数本身发生了超出应有的变化

Thread start passed integer changes itself beyond what it should be

我不知道这是怎么回事。我正在尝试通过生成 100 个线程来不断访问它来测试 class 的线程安全性,但似乎我的匿名方法参数正在将自身更改为它们不应该的值,我对为什么感到困惑。由于我不知道发生了什么,我将 post 测试涉及的所有功能。不知何故,我最终以 "Thread 98" 获取参数 "num = 100"... 这不应该是可能的,我不知道正在发生什么样的 hokey pokey 正在改变整数。 (在方法 "ThreadWriting(int num)" 中,您会看到我检查 "num" 是否等于 100 的地方,我在其中放置了一个断点以捕获该行为中的违规线程,它每次都会中断。否则它在数组 "counts" 上抛出一个 "IndexOutofRangeException"。我只是想看看我的线程是否通常能平等地访问 class 他们都试图同时使用。

    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;
    }

我的所有线程都已命名,如您所见,其中 none 个收到名称 "Thread 100" 所以我不知道其他线程之一如何传递参数 100或者参数可能以某种方式损坏。

显然我的线程安全检查在某些方面不是线程安全的?

这是一个简单的闭包问题,您不应该将 for 循环计数器用作线程参数问题,问题发生在此处,for 循环和线程执行速度不同 运行,因此值我可以为多个线程更改:

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();
        }