让一个方法等到特定事件结束

时间:2010-09-29 09:48:26

标签: c# .net

我遇到一个问题,我发现了许多与多线程相关的类似问题,但没有人联系到我的具体问题。

我有一个方法可以执行某些操作,但是当调用该方法时,我不希望它返回,直到单击一个按钮。

所以基本上,在方法结束时,我希望它保持等待Button_Click事件完成,然后事件应该以某种方式“告诉”方法继续。

目前我通过在方法末尾添加一个循环来完成此操作:

while(someVariable){
  Thread.Sleep(10);
  Application.DoEvents();
}

然后Button_Click事件将someVariable设置为false,然后循环停止。

当然,这看起来非常“不确定”,并且每10毫秒运行一次这个循环似乎是一种巨大的浪费。

有没有办法正确地做到这一点?由于所讨论的方法与应用程序的其余部分在同一个线程上运行,因此暂停该方法不会阻止其他活动的步骤也很重要。

我需要这个的原因是因为当从其他地方调用该方法时,此方法将绘制一些组件(包括两个按钮)。然后用户单击其中一个,然后该方法将根据单击的按钮返回不同的值,并且调用它的程序无法继续,直到它知道单击了哪个按钮。所以我的程序看起来像这样。

....
if( someMethod() == ButtonA ){
  //do the proper action if button 1 is clicked
}else{
  //do the proper action if button 2 is clicked
}

我希望这不会令人困惑。

2 个答案:

答案 0 :(得分:4)

假设这是在UI线程中,你绝对不应该这样做。你说“重要的是停止方法不会阻塞其他活动的线程” - 这基本上意味着你需要找到一个不同的设计。如果UI线程“坚持并等待Button_Click事件完成”,那么在不使用Application.DoEvents()的黑客的情况下它就无法做任何其他事情。

相反,您应该在事件发生时向原始调用者发出 back 的调用。公开调用者可以订阅的事件,并在按钮单击完成时引发该事件,或者让调用者传入委托以适当调用。 (它们实际上是等同的,只是传播回调的不同方式。)

这就是WinForms(和其他富客户端用户界面)的设计方式 - 基本上是基于事件的模型。

答案 1 :(得分:0)

使用AutoResetEvent,请参阅http://msdn.microsoft.com/en-us/library/58195swd.aspx

上的示例和文档

您的主线程在事件上执行WaitOne()并在您的Button.Click事件中,Set()事件。