【问题标题】:List of worker threads spawned by for loop is exceeding for-loop iterationsfor 循环产生的工作线程列表超过了 for 循环迭代
【发布时间】:2015-11-11 11:33:29
【问题描述】:

我对正确的线程比较陌生,我有这个,为了简单起见,它被修改了,但它本质上是一样的:

//Global:
N=2
bool[] mySwitches;

//In my main:

mySwitches = new bool[N];
for (int i = 0; i < N; i++)
{
    ThreadList.Add(new Thread(() => Worker(i)));
    ThreadList[i].Start();
}

//Outside of main:

Private Void Worker(int num)
{
  while(true)
  {
    if (mySwitches[num]) //error happes here because num is equal to N, how?
    {
        //do something
    }
  }
}

如上所示,不知何故,工作线程的值是 num=N,我希望它只会达到 N-1。 我知道在创建 Worker 后我会递增,我是否以某种方式通过引用而不是值传递?

我试图通过在我的 while 循环之前放置一个测试来解决这个问题,如果 num=N 则返回,但即使有这个规定,我也会遇到同样的错误。这让我相信 num 在线程启动后会以某种方式递增。

我通过在 ThreadList[i].Start() 之后直接放置一个 Sleep(20) 解决了这个问题,但是我不太喜欢使用 Sleep,而且很明显我不知道这个线程场景实际上是如何工作的。

任何人都可以对此有所了解吗?

【问题讨论】:

    标签: c# multithreading for-loop


    【解决方案1】:

    i 被其引用捕获。将您的代码更改为

    for (int i = 0; i < N; i++)
    {
        var thInx = i;
        ThreadList.Add(new Thread(() => Worker(thInx)));
        ThreadList[thInx].Start();
    }
    

    欲了解更多信息:http://csharpindepth.com/articles/chapter5/closures.aspx

    【讨论】:

    • 我曾经被这个抓住过一次,但和你一样,我一制作本地副本,一切就都解决了。我认为这是一个容易上当的人
    • 所以它与使用的变量类型没有太大关系,只是编译器将使用相同的变量,直到你创建一个新的本地变量。太棒了,谢谢!
    • 它是最常见的关闭问题,过去曾被发现过一次并吸取了“惨痛的教训”:)
    猜你喜欢
    • 2015-02-03
    • 1970-01-01
    • 1970-01-01
    • 2023-02-23
    • 1970-01-01
    • 1970-01-01
    • 2018-12-18
    • 2021-08-23
    • 1970-01-01
    相关资源
    最近更新 更多