Ahhh yes of course! I'm such an idiot, I know all about the scope of
captured variables (as you can see in the method calling DoAsyncStuff)
but *completely* missed the boat in the DoAsyncStuff method. Thank
you, Pete, for pointing out what should have been obvious to me!
Doh!
On Apr 10, 2:55*pm, "Peter Duniho" <NpOeStPe...@nnowslpianmk.com>
wrote:
> On Fri, 10 Apr 2009 11:32:44 -0700, Anthony Paul <anthonypa...@gmail.com>*
> wrote:
>
> > [...]
> > Everything executes fine, but when both work delegates have finished
> > executing and the UI delegate executes, result2 is the only one that
> > has a value. result1 didn't get updated. If I reverse the order,
> > again, the first delegate doesn't seem to return a value, but the
> > second one does. Does anyone understand what's going on here?
>
> Yes. *You've made the classic error in dealing with captured variables:*
> reusing a loop variable for each delegate instance, rather than providing*
> a new copy of the loop variable for each.
>
> By the time your threads get to run, the loop has finished, and the loop *
> variable is equal to the last value it had. *Thus, both threads use the*
> same value. *In this case, the value is a delegate itself, and so that *
> last delegate is the only one to execute, and it executes twice (in your *
> example, because there are two elements in the array).
>
> The solution is to copy the loop variable to a local variable inside the *
> loop block, so that each delegate instance gets its own copy:
>
> * * *foreach (ThreadStart workDelegate in workDelegates)
> * * *{
> * * * * *ThreadStart workCaptured = workDelegate;
>
> * * * * *ThreadPool.QueueUserWorkItem(
> * * * * * * *delegate()
> * * * * * * *{
> * * * * * * * * *workCaptured();
> * * * * * * * * *if (uiDelegate != null)
> * * * * * * * * *{
> * * * * * * * * * * *// other stuff
> * * * * * * * * *}
> * * * * * * *}, null);
> * * *}
>
> And please, next time ease off the tab-stops. *The indentation in your *
> posted code was a bit ridiculous. *
>
> Pete