Dispatcher.BeginInvoke lambda捕获线程安全吗?

时间:2010-10-11 20:34:12

标签: silverlight thread-safety windows-phone-7 dispatcher concurrency

在Windows Phone 7 / Silverlight中,以下代码是安全的还是竞争条件?

//Snippet 1
foreach(var item in list)
{
   Deployment.Current.Dispatcher.BeginInvoke( () => { foo(item); });
}
肯定(?)这个替代方案很活泼?

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

1 个答案:

答案 0 :(得分:6)

“竞争条件”可能不是解决第一个代码段问题的最佳方法。但基本上,您在捕获范围之外使用捕获的变量。对于所有项目,“item”的值最终将成为最后一项,然后调用foo方法。

相反,这样做:

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

这会将变量放在较低的范围内,并在该范围内捕获。这样可以确保捕获每个值并将其发送到foo

考虑到list变量的合理范围,第二个版本几乎肯定是一个错误。