我有一个对象列表,我想循环该列表并启动一个新线程,传入当前对象。
我写了一个我认为应该这样做的例子,但它不起作用。具体来说,线程似乎在每次迭代中都被覆盖。但这对我来说并没有什么意义,因为我每次都会创建一个新的 Thread 对象。
这是我写的测试代码
class Program
{
static void Main(string[] args)
{
TestClass t = new TestClass();
t.ThreadingMethod();
}
}
class TestClass
{
public void ThreadingMethod()
{
var myList = new List<MyClass> { new MyClass("test1"), new MyClass("test2") };
foreach(MyClass myObj in myList)
{
Thread myThread = new Thread(() => this.MyMethod(myObj));
myThread.Start();
}
}
public void MyMethod(MyClass myObj) { Console.WriteLine(myObj.prop1); }
}
class MyClass
{
public string prop1 { get; set; }
public MyClass(string input) { this.prop1 = input; }
}
我的机器上的输出是
test2
test2
但我预计它会是
test1
test2
我尝试将线程更改为
ThreadPool.QueueUserWorkItem(x => this.MyMethod(myObj));
但没有一个线程启动。
我想我只是对线程应该如何工作有误解。有人可以指出我正确的方向并告诉我我做错了什么吗?
这是因为您关闭了错误范围内的变量。这里的解决方案是在 foreach 循环中使用临时变量:
foreach(MyClass myObj in myList)
{
MyClass tmp = myObj; // Make temporary
Thread myThread = new Thread(() => this.MyMethod(tmp));
myThread.Start();
}
有关详细信息,我建议阅读 Eric Lippert 关于此主题的帖子:关闭循环变量被认为是有害的 http://blogs.msdn.com/b/ericlippert/archive/2009/11/12/closing-over-the-loop-variable-considered-harmful.aspx
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)