multithreading re-entrancy issue

后端 未结 3 1125
被撕碎了的回忆
被撕碎了的回忆 2021-01-27 19:26

I\'m trying to spawn different threads for some processing. I use the for loop index for some logic inside each thread.
How can I get the different threads to p

相关标签:
3条回答
  • 2021-01-27 20:17

    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

    0 讨论(0)
  • 2021-01-27 20:24

    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:

    • Access to Modified Closure
    • Access to Modified Closure (2)
    • C# Captured Variable In Loop
    • ReSharper Warning - Access to Modified Closure
    • modified closure warning in ReSharper
    • From Eric Lippert's blog: “don't close over the loop variable” [duplicate]
    • Why is it bad to use an iteration variable in a lambda expression
    • How do I get around this lambda expression outer variable issue?
    • Strange behavior when using lambda expression on WPF buttons click event
    • C# - The foreach identifier and closures
    • How to tell a lambda function to capture a copy instead of a reference in C#?
    • Why do I get: “iteration variable in a lambda expression may have unexpected results” [duplicate]
    • Does this code really cause an “access to modified closure” problem?
    • Why is it bad to use an iteration variable in a lambda expression
    • How to suppress VB's “Iteration variable shouldn't been used in lambda expression”
    • Run multiply instances of the same method simultaneously in c# without data loss?
    • What are the correct semantics of a closure over a loop variable? [closed]
    • C# under the hood code generation for lambdas within loops
    • What is the correct way to dynamically add an undetermined number of clauses to a Linq 2 Sql query?
    • etc.
    0 讨论(0)
  • 2021-01-27 20:31

    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)
    
         );
     }
    
    0 讨论(0)
提交回复
热议问题