multithreading重入问题
我正在尝试为某些处理生成不同的线程。 我for
每个线程中的一些逻辑使用for
循环索引。
如何在下面的代码中获取不同的线程来打印1,2,3,4,5? 每次我运行这个,我得到不同的数字作为输出 – 3,3,3,4,6,6和2,2,3,5,5,6等。
我尝试使用锁定对象,但它没有正确执行。 任何人都可以帮我解决这个问题。 我只是想确保每个线程/任务获得正确的索引。 请注意,每个任务都被强制在单独的线程上运行。
List tasks1 = new List(); for (int j = 1; j { Console.WriteLine(j); } , new CancellationToken() , TaskCreationOptions.LongRunning , TaskScheduler.Default) ); } Task.WaitAll(tasks1.ToArray()); Console.Read();
你正在“捕获循环变量”。 j
在lambda中使用的事实意味着编译器将以不同的方式对待它(实质上,它将被装箱)并且所有线程将使用相同的共享变量。
简短修复:
for (int j = 1; j <= 5; j++) { int jCopy = j; tasks1.Add(Task.Factory.StartNew(() => { Console.WriteLine(jCopy); }, new CancellationToken(), TaskCreationOptions.LongRunning, TaskScheduler.Default) ); }
只是为了完成其他答案。 在C#5.0(.NET 4.5)中,关闭foreach
循环变量有一个重大变化,但是没有关闭for
循环变量。
请参阅Eric Lippert的详细信息(和前言更新说明) 。 关闭循环变量被认为是有害的 ,他的Closing over the loop变量,第二部分
请注意,此问题与multithreading或TPL(任务并行库)用法无关。
其他答案和评论提到它之前已经讨论过,但没有链接到任何先前的答案。 以下是一些,为了相互联系:
- 访问修改后的关闭
- 获得修改后的封闭(2)
- C#捕获变量循环
- ReSharper警告 – 访问修改后的关闭
- ReSharper中修改了闭包警告
- 来自Eric Lippert的博客:“不要关闭循环变量”[重复]
- 为什么在lambda表达式中使用迭代变量是不好的
- 我如何解决这个lambda表达式外部变量问题?
- 在WPF按钮上单击事件时使用lambda表达式时出现奇怪的行为
- C# – foreach标识符和闭包
- 如何告诉lambda函数在C#中捕获副本而不是引用?
- 为什么我会得到:“lambda表达式中的迭代变量可能会产生意外结果”[重复]
- 此代码是否真的导致“访问修改后的闭包”问题?
- 为什么在lambda表达式中使用迭代变量是不好的
- 如何抑制VB的“迭代变量不应该在lambda表达式中使用”
- 在c#中同时运行相同方法的多个实例而不会丢失数据?
- 闭包对循环变量的正确语义是什么? [关闭]
- 循环中lambdas的引擎代码生成下的C#
- 向Linq 2 Sql查询动态添加未确定数量的子句的正确方法是什么?
- 等等
回答了数百万次。 它与关闭有关。 更改您的代码如下
for (int j = 1; j <= 5; j++) { int temp = j; tasks1.Add(Task.Factory.StartNew(() => { Console.WriteLine(temp); }, new CancellationToken(), TaskCreationOptions.LongRunning, TaskScheduler.Default) ); }
我建议你阅读: 循环变量和闭包
- Linq to Entities Group By(OUTER APPLY)“oracle 11.2.0.3.0不支持申请”
- 如何使用Nhibernate在asp.net mvc中实现session-per-request模式
- JNI4Net C#到Java
- GetValue,GetConstantValue和GetRawConstantValue之间的区别
- 如何写入隐藏文件?
- 为什么我在这种情况下打印出System.char ?
- 按子网掩码计算IP范围
- 为什么我不能将资源用作具有DataAnnotations的ErrorMessage?
- 如何从网站上传Excel文件并以编程方式将数据导入SQL Server?