[英]ManualResetEvent.WaitOne() throws NullReferenceException: Object reference not set to an instance of an object
[英]ManualResetEvent throws NullReferenceException: Object reference not set to an instance of an object
代碼拋出
NullReferenceException:對象引用未設置為對象的實例
在線上((ManualResetEvent)handles[i]).Set()
。 調試時,我檢查了handles [i]是否具有值。 我究竟做錯了什么?
` 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);`
發生的是您在線程中使用了i
地方修改了閉包 。
i
的值在((ManualResetEvent)handles[i]).Set();
使用前要遞增((ManualResetEvent)handles[i]).Set();
,到那時您還沒有設置handles[i]
的值。
發生這種情況是因為調用線程立即轉到下一行代碼i++;
在執行新線程之前((ManualResetEvent)handles[i]).Set();
。 這是經典的比賽條件。
要解決此問題,請在啟動線程之前添加以下行:
int j = i;
然后在((ManualResetEvent)handles[i]).Set();
使用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++;
}
當然,當您在調試器下運行代碼時,線程已完全更改,因此您沒有發現問題。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.