启动并等待多个线程 - Resharper抱怨修改后的闭包

时间:2012-09-20 21:45:21

标签: c# .net multithreading resharper

我正在尝试按照此处的建议实施多线程:Spawn Multiple Threads for work then wait until all finished

代码如下:

var resetEvent = new ManualResetEvent(false);
            var clientsCount = IDLocal.UserSessions.Count;

            // Load sessions:
            IDLocal.UserSessions = new IDSessions();

            // Start thread for each client 
            foreach (IDSession session in IDLocal.UserSessions)
            {
                var clnt = session;
                new Thread(
                    delegate()
                    {
                        Debug.WriteLine(Thread.CurrentThread.ManagedThreadId);
                        clnt.FailedToRespond = !this.SendDirect(data, this.GetHostAddress(clnt.HostName), clnt.PortNumber);

                        // If we're the last thread, signal 
                        if (Interlocked.Decrement(ref clientsCount) == 0) resetEvent.Set();
                    })
                    .Start();
            }

我在这里收到ReSharper警告:if (Interlocked.Decrement(ref clientsCount) == 0)

它表明我正在访问修改后的闭包(clientsCount)

这是一个有效的建议吗?

1 个答案:

答案 0 :(得分:3)

该警告旨在涵盖诸如

之类的代码
int i = 1;
Func<int> f = () => i + 1;
i = 2;
int j = f(); // What does this set j to?

调用i时将使用f的更新值。警告建议将此更改为

int i = 1;
int icopy = i;
Func<int> f = () => icopy + 1;
i = 2;
int j = f(); // Now what does this set j to?

,如果,您希望f查看创建委托时的i值。在foreach循环的上下文中,很容易产生不直观的行为。 C#5中foreach循环的含义发生了变化,正是因为这一点。

由于这不是您想要的,因为您确实希望看到对捕获变量的更改,请不要更改代码中的任何内容。