簡體   English   中英

ManualResetEvent引發NullReferenceException:對象引用未設置為對象的實例

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM