我總共有三個線程。第一個是主UI線程,該線程啓動System.Threading.Thread
(ExperimentThread
),後者又啓動BackgroundWorker
(WorkerThread
)。Thread.Join()導致死鎖
MainThread
和WorkerThread
都訪問共享資源。我同步與下列對象訪問此資源:
private static readonly Object LockObject = new Object();
,我用在每個線程的主循環如下:
lock (LockObject)
{
// Do something with shared resource here.
}
的ExperimentThread
一個簡化版本如下:
public void RunExperiment
{
while (!bStopThread)
{
lock (LockObject)
{
// Do something with shared resource here.
}
if (bStopThread)
{
break;
}
else
{
Application.DoEvents();
Thread.Sleep(250);
}
}
}
而對於完整性這裏是WorkerThread
的DoWork的方法:
private void Worker_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker Worker = sender as BackgroundWorker;
for (int X = 0; X < 200; X++)
{
if (Worker.CancellationPending)
{
e.Cancel = true;
return;
}
lock (LockObject)
{
// Do something with shared resource here.
}
}
}
這似乎工作正常,當兩個線程都自由運行。
在一些點,UI線程將通過設置它的布爾字段設置爲true的一個終止ExperimentThread
,然後等待它結束,如下所示:一旦
if (ExperimentThread.IsAlive)
{
ExperimentThread.StopThread = true;
ExperimentThread.Join(); // this line seems to cause the deadlock?
}
爲加入()被調用時,正在訪問的共享資源上出現死鎖ExperimentThread
和WorkerThread
,並且我的應用程序無限期地掛起。這可能發生在10次中的9次。
如果從我上面的代碼段刪除ExperimentThread.Join()
,僵局永遠不會發生,並ExperimentThread
似乎正常終止(它然後繼續通過調用CancelAsync()
終止WorkerThread
)。
任何想法可能是這裏的問題? (PS我一直在使用Console.WriteLine()來確定什麼時候獲取和釋放鎖,這是什麼導致我相信有一個死鎖。有沒有更好的來確定這一點,我可能是錯的? )
你可以包含你的'ExperimentThread'執行的代碼嗎? –
沒有足夠的代碼顯示此處以確定真正原因... –
'Thread.Join()導致死鎖' - yup,這只是Join()的正常行爲,或任何其他類型的硬等待,在GUI應用程序事件處理程序。我已經看到幾十年來以各種語言使用各種語言死鎖的圖形用戶界面,但我們仍然得到'你必須等待線程從加入/等待/任何'結束從愚蠢的線程介紹網站。 35年來爲缺乏經驗的多線程開發人員餵養了同樣的垃圾。 –