2012-09-20 26 views
2

我想實現多線程的建議在這裏:Spawn Multiple Threads for work then wait until all finished開始等待多個線程 - ReSharper的抱怨修改封

代碼看起來像這樣:

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)

那是一個有效的SUG GESTION?

+1

是的,這是一個有效的建議。應該避免變量關閉變量。 –

+0

這不是規則的例外,因爲他正在變異的值是要跨線程共享的變量? – dugas

+3

@dugas是的,這不是警告的一個例子,所以在這裏應該忽略警告。警告是關於捕獲變量而沒有意識到它們的值會改變。在這種情況下,您想要更改這些值。 – hvd

回答

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循環的含義發生了變化。

由於這不是你想要的,因爲你確實想看到捕獲變量的變化,所以不要在代碼中改變任何東西。

+0

我這麼認爲。特別是它指的是'ref'的變量,Resharper應該比這更聰明。 – katit