gpt4 book ai didi

c# - 从循环中启动线程并传递循环 ID

转载 作者:太空宇宙 更新时间:2023-11-03 18:00:57 25 4
gpt4 key购买 nike

我今天刚开始玩线程,遇到了一些我不明白的事情。

public void Main()
{
int maxValue = 5;
for (int ID = 0; ID < maxValue; ID++)
{
temp(ID);
}
}

public void temp(int i)
{
MessageBox.Show(i.ToString());
}

虽然基本但工作正常,但是当我尝试为每个线程创建一个新线程时,它只传递了 maxValue。请忽略这样做有多糟糕,我只是作为一个简单的例子这样写的。

public void Main()
{
int maxValue = 5;
for (int ID = 0; ID < maxValue; ID++)
{
threads.Add(new Thread(() => temp(myString, rowID)));
threads[rowID].Start();
}
}

public void temp(string myString, int i)
{
string _myString = myString;

MessageBox.Show(i.ToString());
}

鉴于此,我有两个问题:1) 为什么不在传递 ID 的新线程上调用该方法?2) 应该如何正确编码?

最佳答案

问题是您只有一个 ID 变量,而且它正在被捕获。变量仅在新线程中的代码实际执行时才被读取,这通常是在您的主线程完成其循环之后,ID 留在 最大值。在每次循环迭代时复制一份,以便每次捕获不同的变量:

for (int ID = 0; ID < maxValue; ID++)
{
int copy = ID;
threads.Add(new Thread(() => temp(myString, copy)));
threads[rowID].Start();
}

这是闭包的常见错误。阅读my article comparing C# and Java closures了解更多信息。顺便说一句,foreach 也会发生同样的事情 - 这更令人困惑,因为它读起来就像你每次都有一个新变量一样:

foreach (string url in urls)
{
// Aargh, bug! Don't do this!
new Thread(() => Fetch(url)).Start();
}

同样,您最终只会得到一个变量。您需要每个委托(delegate)来捕获一个单独的变量,因此您再次使用一个副本:

foreach (string url in urls)
{
string urlCopy = url;
new Thread(() => Fetch(urlCopy)).Start();
}

关于c# - 从循环中启动线程并传递循环 ID,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1423680/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com