c#foreach with Action.BeginInvoke

Kel*_*ton -1 c# concurrency delegates action invoke

好吧,所以我在这里遇到了一些问题.这是循环.

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));
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

这是LazyAsync

public static class LazyAsync
{
    public static void Invoke(Action a)
    {
        a.BeginInvoke(a.EndInvoke, null);
    }
}
Run Code Online (Sandbox Code Playgroud)

每个Client包含一个socket,所以我不能Clone这么做.问题是,当我执行Invoketo时c.WriteMessage,由于执行被延迟,它通常不会触发列表中的第一对,并且有时实际上只会在最后一项上触发一大堆.

我知道这与c是一个在Invoke实际被调用之前发生变化的引用有关,但有没有办法避免这种情况?

执行一般for(int i=0 etc循环似乎无法解决此问题.

任何人对我如何解决这个问题都有任何想法?

记住,不能Clone Client.

Cod*_*lla 5

将您复制c到本地变量,如下所示:

lock (ClientLocker)
{
    Trace.WriteLine("#WriteAll: " + sm.Header);
    foreach (Client c in Clients)
    {
        if (c.LoggedIn)
        {
            Client localC = c;
            Trace.WriteLine("#TryWriteTo[" + c.Id + "](" + sm.Header + ")");
            LazyAsync.Invoke(() => localC.WriteMessage(sm));
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

如果您想获得更多信息,请进行网络搜索:"访问修改后的闭包".