More Deferred Execution Fun: foreach and delegation scope
This is closely related to my last post on deferred execution gotchas and its basically more "if you inline delegated code, you may easily overlook scope side-effects". This time it's about dealing with foreach and using the local each item for deferred execution.public void SpawnActions() { foreach (ActionContext context in contexts) { int id = context.Id; Action<int> callback = (workerNumber) => { Console.WriteLine("{0} Id: {1}/{2}", workerNumber, id, context.Id); }; ThreadPool.QueueUserWorkItem(new WaitCallback(FutureExecute), callback); } } public void FutureExecute(object state) { int id = worker++; Action<int> callback = state as Action<int>; Thread.Sleep(500); callback(id); }
The output looks like this:
0 Id: 0/9 1 Id: 1/9 2 Id: 2/9 3 Id: 3/9 4 Id: 4/9 5 Id: 5/9 6 Id: 6/9 7 Id: 7/9 8 Id: 8/9 9 Id: 9/9
foreach (ActionContext context in contexts) { int id = context.Id; // locally scoped variable ActionContext c2 = context; Action<int> callback = (workerNumber) => { Console.WriteLine("{0} Id: {1}/{2}", workerNumber, id, c2.Id); }; ThreadPool.QueueUserWorkItem(new WaitCallback(FutureExecute), callback); }
And now our results are a bit more what we expected:
0 Id: 0/0 1 Id: 1/1 2 Id: 2/2 3 Id: 3/3 4 Id: 4/4 5 Id: 5/5 6 Id: 6/6 7 Id: 7/7 8 Id: 8/8 9 Id: 9/9

0 Comments:
Post a Comment
<< Home