2016-09-06 38 views
0

的代碼拋出ManualResetEvent的拋出的NullReferenceException:對象沒有設置爲一個對象

的NullReferenceException的一個實例:不設置爲一個對象

的實例就行((ManualResetEvent)handles[i]).Set()對象引用。我檢查手柄[我]有一個值,當我調試它。我究竟做錯了什麼?

`    string[] fileEntries = Directory.GetFiles(pathFife); 
       ManualResetEvent[] handles = new ManualResetEvent[fileEntries.Count()]; 
       int i = 0; 
       foreach (string fullName in fileEntries) 
       { 
        handles[i] = new ManualResetEvent(false); 
         var thread = new Thread(() => 
          { 
           AddFile(fullName, month, year, user); 
           ((ManualResetEvent)handles[i]).Set(); 
          }); 
         thread.Start(); 
        i++; 
       } 
       WaitHandle.WaitAll(handles);`  

回答

0

發生了什麼事是你有ia modified closure在那裏的線程中使用。

i值遞增之前它在((ManualResetEvent)handles[i]).Set();使用,在這一點上你沒有設置的handles[i]值。

發生這種情況是因爲在新線程執行((ManualResetEvent)handles[i]).Set();之前調用線程立即進入下一行代碼i++;。這是一個經典的競賽條件。

要解決此問題,添加以下行啓動線程之前:

int j = i;

然後用j代替i((ManualResetEvent)handles[i]).Set();

foreach (string fullName in fileEntries) 
{ 
    handles[i] = new ManualResetEvent(false); 
    int j = i; 
    var thread = new Thread(() => 
    { 
     AddFile(fullName, month, year, user); 
     ((ManualResetEvent)handles[j]).Set(); 
    }); 
    thread.Start(); 
    i++; 
} 

當然,當你在調試器下運行代碼,線程完全改變了,因此你沒有看到問題。

+0

@Downvoter:小心解釋這個答案有什麼問題?否則,downvote對任何人都不是很有幫助。 –

相關問題