我有一個Windows Forms應用程序與BackgroundWorker。在主窗體上的一個方法中,顯示一個MessageBox,用戶必須點擊OK按鈕繼續。同時,在顯示消息框時,BackgroundWorker完成執行並調用RunWorkerCompleted事件。在我已經分配給在UI線程上運行的事件的方法中,將在窗體上調用Close方法。即使顯示消息框的方法仍在運行,UI線程也不會阻止其他線程調用它的方法。所以Close方法在窗體上被調用。我想要的是UI線程阻止其他線程的調用,直到消息框的方法結束。有沒有簡單的方法來做到這一點?在C#或.NET中,是否有辦法阻止其他線程調用特定線程上的方法?
4
A
回答
1
我想你應該更關心你的事件如何處理。您不想停止在UI線程上調用的方法,因爲方法調用機制與允許鼠標和鍵盤事件等工作的方法調用機制相同。如果你阻止方法調用,你也會阻止它。相反,您需要以某種方式延遲方法。您可能需要編寫自己的同步代碼才能執行此操作。
0
使用ManualResetEvent控制RunWorkCompleted事件和顯示MessageBox的方法之間的同步。
0
對此,您可以使用簡單的lock
。在您的形式,像這樣創建窗體級成員:
private object _locker = new object();
然後讓你的代碼獲取兩種方法的鎖,就像這樣:
private void RunWorkerCompleted()
{
lock (_locker)
{
this.Close();
}
}
private void ShowSomeMessage()
{
lock (_locker)
{
MessageBox.Show("message");
}
}
如果你的代碼是目前在ShowSomeMessage()
阻塞(即消息框仍然打開),RunWorkerCompleted()
方法將在關閉表單之前等待消息框關閉(釋放鎖定)。
更新:這應該工作,無論哪個線程正在調用什麼:
private bool _showingMessage = false;
然後讓你的代碼獲取鎖在兩種方法中,像這樣:
private void RunWorkerCompleted()
{
while (_showingMessage)
{
Thread.Sleep(500); // or some other interval (in ms)
}
this.Close();
}
private void ShowSomeMessage()
{
_showingMessage = true;
MessageBox.Show("message");
_showingMessage = false;
}
相關問題
- 1. C#阻止從其他線程訪問所有對象方法
- 2. OpenMP:是否有線程終止所有其他並行線程的方法?
- 3. Spring的PROPAGATION_REQUIRED方法是否阻塞其他線程?
- 4. 在主線程或後臺線程中是否會調用NSNotificationCenter回調方法?
- 5. 在特定線程調用方法,而在另一個線程
- 6. 如何在用戶調用特定方法之前阻止當前線程?
- 7. 阻塞線程的調用方法
- 8. Python阻塞的線程終止方法?
- 9. 有沒有辦法確定.NET線程何時終止?
- 10. C#在新線程中調用方法
- 11. 如何在其他線程上排列我的方法回調?
- 12. 如何從C#中的其他線程調用線程?
- 13. C#ThreadPool一個線程阻塞其他?
- 14. 線程終止時調用方法
- 15. sem_wait上的線程阻塞導致其他線程掛起
- 16. IO操作在其他線程中阻塞我的UI線程?
- 17. 在主線程上調用方法?
- 18. 禁用「CheckForIllegalCrossThreadCalls」是阻止跨線程錯誤的好方法嗎?
- 19. 阻止主線程完成其執行的最佳方法
- 20. GC是否停止.NET中的所有應用程序線程?
- 21. .NET「Timer」會阻止其他方法調用?
- 22. SetEvent是否會阻止一個或所有等待的線程?
- 23. 在給定線程ID的情況下在特定線程上運行方法
- 24. 回調阻止線程
- 25. 我可以在調用UI線程上的方法時阻止我的服務線程?
- 26. 在Django中阻塞網絡調用阻止所有線程?
- 27. 在.Net中阻塞線程
- 28. C#線程方法
- 29. 有沒有辦法阻止後臺線程沒有進程殺死Android?
- 30. 從C#中的線程更新UI的其他方法
這是我最初嘗試過的。但它不起作用,因爲我相信這兩種方法在同一個線程上運行。並且,當RunWorkerCompleted()獲取到鎖語句時,它不會因爲它所運行的線程已經擁有該鎖而被阻塞。如果我錯了,請糾正我。 – YWE 2010-04-30 19:18:12
這聽起來不對,除非通過'Invoke'或'BeginInvoke'調用這些方法之一。如果從按鈕單擊中顯示消息框,則該消息框位於UI線程上,該線程應該與後臺工作線程不同。 – MusiGenesis 2010-04-30 19:24:21
我也嘗試過第二種方式。它有點作品。但它遭受了Stewert提到的問題。 UI線程無法響應鼠標點擊,因此用戶無法單擊確定。它導致了一種「僵局」。 – YWE 2010-04-30 19:47:49