Dispatcher.BeginInvoke лямбда-захват потокобезопасный? - PullRequest
2 голосов
/ 12 октября 2010

В Windows Phone 7 / Silverlight является ли следующий код безопасным или это условие гонки?

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

Конечно (?) Эта альтернатива является racy?

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

1 Ответ

6 голосов
/ 12 октября 2010

«Состояние гонки» может быть не лучшим способом решить проблему с первым фрагментом. Но в основном вы используете захваченную переменную вне области захвата. Значение "item" в конечном итоге будет last item , тогда будет вызван ваш метод foo для всех элементов.

Вместо этого сделайте следующее:

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

Это помещает переменную в более низкую область, и она захватывается в этой области. Это гарантирует, что каждое значение будет перехвачено и отправлено на foo.

Вторая версия почти наверняка является ошибкой, учитывая здравый смысл переменной list.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...