Rule Idea: Find loop variables which are incorrectly used in a closure


This rule can best be described as follows:
Flag any Action or Func or delegate, which is passed to an Async Method or Event declaration which uses a local variable which is changed after the Async Method. Or a Action or Func or delegate which reads from a Property or Field and is being passed to an Async method or Event declaration.
Exceptions: When proper thread synchronization occurs (might be hard to detect, usage of Mutex, Reader/Writer, WaitHandle, Thread.Join)
Remedy: use the overloads which allow the passing of a parameter instead of passign the parametr directly into the closure.
Taken from:
Ha ha! You fool! You fell victim to one of the classic blunders - The most famous of which is "never get involved in a land war in Asia" - but only slightly less well-known is this: "Never go against a Sicilian when death is on the line"!  (Princess Bride)
And only slightly less well known than those two is:  never create a closure on a loop variable.
What you want to do is use a parameterized start function.
Something like: Task.Factory.StartNew((x) => CalcFact.RunCals(Grps[x]), i);
This overload of StartNew passes in a function (Which is Action<object>) and the object to pass in.  This way your function takes an argument (x) and i is safely hidden from the thread function.
the value of i is known at the time of queueing of the tasks.  If you reveal the loop variable to the lambda function, then the lambda function is executed in the thread pool at some random time after the task was queued.  I would suspect that maybe one of them would have the value of 0, but most of them will execute after all the tasks are queued.  and what's i equal to after all the tasks are queued?  100!
The parameterized start will remember the correct value of i to pass in to the thread function when it invokes.
Beware of closures on loop variables, and beware of Iocane powder!  ;)  (No offense taken on that movie quote, I hope!)

file attachments

Closed Jan 13, 2013 at 9:16 PM by jessehouwing