2016-09-06 26 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对任何人都不是很有帮助。 –

相关问题