[英]Thread doesn't wake up after join
我有一個具有開始和取消按鈕的GUI界面。 啟動之后,主線程(即GUI線程)正在創建第二個線程,它將執行實際工作。 當按下取消按鈕時,它所做的就是設置一個布爾值,該值告訴工作線程停止其工作並結束。 問題是,即使我確定工作線程已完成其工作,主GUI線程仍會卡住。 這是為什么?
這是一些代碼:
private Thread workerThread;
private SomeClass fs;
private void buttonSearch_Click(object sender, EventArgs e)
{
//do some initializations
fs = new SomeClass();
workerThread = new Thread(fs.WorkMethod);
workerThread.Start();
}
private void buttonCancel_Click(object sender, EventArgs e)
{
fs.StopWork();
workerThread.Join();
}
inside SomeClass:
private bool keepWorking;
public void StopWork()
{
keepWorking= false;
}
public void WorkMethod()
{
if (keepWorking)
{
//do some stuff with recursion
}
}
有人知道調用join之后主線程為什么不喚醒嗎? 我還嘗試調試,以查看如果我將keepWorking變量手動更改為false且該方法確實到達末尾會發生什么。
您的WorkMethod
在那里有一個調用Invoke
,該調用正在調用委托以在UI線程上運行,然后阻塞直到完成。 由於您的UI線程當前正在阻塞等待后台線程的Join
調用,因此UI線程無法調用該委托。
現在,您的兩個線程都互相等待,並且沒有任何進展。 這稱為“死鎖”。
另外, keepWorking
應該被標記為volatile
因為它正在從多個線程訪問。 照原樣,后台線程可以在主線程對其進行更改之后的相當一段時間內訪問該變量的過時/緩存值。 將其標記為volatile
阻止運行時進行此類優化。
解決方案是不通過調用Join
阻塞UI線程。 如果需要在后台線程結束時執行一些代碼,則需要在線程結束時異步觸發該代碼,而不是同步阻塞。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.