开发者

Dispatcher.BeginInvoke lambda capture thread-safe?

In Windows Phone 7 / Silverlight, is the following code safe or is it a race condition?

//Snippet 1
foreach(var item in list)
{
   Deployment.Current.Dispatcher.BeginInvoke( () => { foo(item); });
}

Surely (?) this alternative is racy?

//Snippet 2
Deployment.Current.Dispatcher.BeginInvoke( () => 
   { 
      开发者_运维百科 foreach(var item in list){ foo(item); }
   });
list.Clear();


"Race condition" may not be the best way to put the problem with the first snippet. But basically, you are using a captured variable outside the capture scope. The value of "item" will end up being the last item then your foo method is called, for all items.

Instead, do this:

foreach(var item in list)
{
   var tmpItem = item;
   Deployment.Current.Dispatcher.BeginInvoke( () => foo(tmpItem));
}

This puts a variable in a lower scope, and it is captured in that scope. This makes sure that each value is captured and sent to foo.

The second version is almost certainly an error given a sane scope of the list variable.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜