我有一个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