在C#或.NET中,是否有方法防止其他线程调用特定线程上的方法?
我有一个带BackgroundWorker的Windows窗体应用程序。在主窗体上的方法中,会显示一个消息框,用户必须单击OK按钮才能继续。同时,在显示messagebox时,BackgroundWorker完成执行并调用RunWorkerCompleted事件。在我分配给该事件的方法(在UI线程上运行)中,在表单上调用Close方法。即使显示消息框的方法仍在运行,UI线程也不会阻止其他线程调用其上的方法。因此在表单上调用Close方法。我想要的是UI线程阻止其他线程的调用,直到带有消息框的方法完成。有简单的方法吗?使用ManualResetEvent来控制RunWorkCompleted事件和显示MessageBox的方法之间的同步。您可以使用简单的在C#或.NET中,是否有方法防止其他线程调用特定线程上的方法?,c#,.net,multithreading,C#,.net,Multithreading,我有一个带BackgroundWorker的Windows窗体应用程序。在主窗体上的方法中,会显示一个消息框,用户必须单击OK按钮才能继续。同时,在显示messagebox时,BackgroundWorker完成执行并调用RunWorkerCompleted事件。在我分配给该事件的方法(在UI线程上运行)中,在表单上调用Close方法。即使显示消息框的方法仍在运行,UI线程也不会阻止其他线程调用其上的方法。因此在表单上调用Close方法。我想要的是UI线程阻止其他线程的调用,直到带有消息框的方法
锁来实现这一点。在表单中,创建一个表单级成员,如下所示:
private object _locker = new object();
private void RunWorkerCompleted()
{
lock (_locker)
{
this.Close();
}
}
private void ShowSomeMessage()
{
lock (_locker)
{
MessageBox.Show("message");
}
}
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;
}
然后让您的代码在两种方法中都获得锁,如下所示:
private object _locker = new object();
private void RunWorkerCompleted()
{
lock (_locker)
{
this.Close();
}
}
private void ShowSomeMessage()
{
lock (_locker)
{
MessageBox.Show("message");
}
}
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;
}
如果您的代码当前在ShowSomeMessage()
中阻塞(即消息框仍然打开),RunWorkerCompleted()
方法将等待消息框关闭(释放锁)后再关闭表单
更新:无论哪个线程调用什么,这都应该有效:
private bool _showingMessage = false;
然后让您的代码在两种方法中都获得锁,如下所示:
private object _locker = new object();
private void RunWorkerCompleted()
{
lock (_locker)
{
this.Close();
}
}
private void ShowSomeMessage()
{
lock (_locker)
{
MessageBox.Show("message");
}
}
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;
}
我认为你应该在处理事件的方式上更加自律。您不希望停止在UI线程上调用方法,因为方法调用机制与允许鼠标和键盘事件等工作的机制相同。如果您阻止方法调用,您也将阻止该调用。相反,您需要以某种方式延迟这些方法。您可能需要编写自己的同步代码来执行此操作。这是我最初尝试的。但它不起作用,因为我相信,这两个方法运行在同一个线程上。当RunWorkerCompleted()到达lock语句时,它不会阻塞,因为它运行的线程已经有了锁。如果我错了,请纠正我。这听起来不对,除非通过Invoke
或BeginInvoke
调用其中一个方法。如果消息框是通过单击按钮显示的,那么它将位于UI线程上,这应该与后台工作线程不同。我也尝试了第二种方法。这有点管用。但它也有斯图尔特提到的问题。UI线程无法响应鼠标单击,因此用户无法单击“确定”。它会导致一种“死锁”。