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

Lar*_*ien 2 silverlight concurrency dispatcher thread-safety windows-phone-7

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

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

当然(?)这个替代品很活泼?

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

Phi*_*eck 6

"竞争条件"可能不是解决第一个代码段问题的最佳方法.但基本上,您在捕获范围之外使用捕获的变量."项目"的价值最终会被的最后一个项目,然后你的foo方法被调用,所有项目.

相反,这样做:

foreach(var item in list)
{
   var tmpItem = item;
   Deployment.Current.Dispatcher.BeginInvoke( () => foo(tmpItem));
}
Run Code Online (Sandbox Code Playgroud)

这会将变量放在较低的范围内,并在该范围内捕获.这可确保捕获并发送每个foo.

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