Хорошо, так что у меня здесь проблема. Вот петля.C# foreach with Action.BeginInvoke
lock (ClientLocker)
{
Trace.WriteLine("#WriteAll: " + sm.Header);
foreach (Client c in Clients)
{
if (c.LoggedIn)
{
Trace.WriteLine("#TryWriteTo[" + c.Id + "](" + sm.Header + ")");
LazyAsync.Invoke(() => c.WriteMessage(sm));
}
}
}
Вот LazyAsync
public static class LazyAsync
{
public static void Invoke(Action a)
{
a.BeginInvoke(a.EndInvoke, null);
}
}
Каждый Client
содержит socket
, так что я не могу с трудом Clone
это. Проблема заключается в том, что когда я делаю Invoke
до c.WriteMessage
, так как исполнение задерживается, оно обычно не срабатывает по первой паре в списке, и иногда на самом деле будет срабатывать только целая куча на самом последнем элементе.
Я знаю, что это связано с тем, что c является ссылкой, которая изменяется до того, как Invoke
действительно вызван, но есть ли способ избежать этого?
Выполнение общего цикла for(int i=0 etc
, похоже, не устраняет эту проблему.
У кого-нибудь есть идеи о том, как я могу это исправить?
Помните, что не может Clone
Client
.
Кто-то спрашивает об этом почти каждый день. См. Http://stackoverflow.com/questions/8898925/is-there-a-reason-for-cs-reuse-of-the-variable-in-a-foreach/8899347#8899347 для некоторых ссылок и обсуждения вопроса , –
Я сделал поиск, но ничего не нашел. Не так, как я не пытался. –
Действительно; это трудно найти. Именно поэтому этот вопрос задают снова почти каждый день. Если вы на самом деле не получите предупреждение «доступ к модифицированному закрытию» от resharper, нет никакой причины, по которой вы знаете, какие ключевые слова для поиска. –