multithreading re-entrancy issue

那年仲夏 提交于 2019-12-02 09:17:36

You are 'capturing the loop variable'. The fact that j is used inside the lambda means the compiler will treat it differently (in essence, it will be boxed) and all thread will use the same shared variable.

The short fix:

 for (int j = 1; j <= 5; j++)
 {
     int jCopy = j;

     tasks1.Add(Task.Factory.StartNew(() =>
      {
          Console.WriteLine(jCopy);
      }, new CancellationToken(), TaskCreationOptions.LongRunning, TaskScheduler.Default)

     );
 }
Gennady Vanin Геннадий Ванин

Just to complete the other answers. In C# 5.0 (.NET 4.5) there was a breaking change in relation to closing over foreach loop variable, but not to closure over for loop variable.

See details (and preface Update note) in Eric Lippert. Closing over the loop variable considered harmful and his Closing over the loop variable, part two

Note that this issue is independent on multithreading or TPL (Task Parallel Library) usage.

The other answers and comments mentioned that it was discussed before but there was no linking to any of the previous answers. Here are some, for the sake of inter-linking:

Answered millions of times. it is related with closure. Change your code as below

 for (int j = 1; j <= 5; j++)
 {
     int temp = j;

     tasks1.Add(Task.Factory.StartNew(() =>
      {
          Console.WriteLine(temp);
      }, new CancellationToken(), TaskCreationOptions.LongRunning, TaskScheduler.Default)

     );
 }

I would recomment to read this: Loop variables and Closures

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!