C#:方法被连续调用两次
这是我的代码。C#:方法被连续调用两次
BackgroundWorker exportWorker = new BackgroundWorker();
private void btnOK_Click(object sender, RoutedEventArgs e)
{
exportWorker.DoWork += new DoWorkEventHandler(ExportWorkerDoWork);
exportWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(ExportWorkerRunWorkerCompleted);
exportWorker.RunWorkerAsync();
}
void ExportWorkerDoWork(object sender, DoWorkEventArgs e)
{
MethodToPerformInThisThread();
**Dispatcher.Invoke(new Action(() => {MethodofAnotherThreadThatChangesUIStuff();}**
}
void ExportWorkerRunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
}
- 当我点击确定按钮(
btnOK_Click
)第一次,它会提前 并运行一切就好了。现在 - ,如果我确定按钮点击第二次代码有 执行完毕,在大胆的运行代码的两倍,这意味着 方法
MethodofAnotherThreadThatChangesUIStuff();
被称为连续两次 后。 - 再次,如果我第三次单击确定按钮,
MethodofAnotherThreadThatChangesUIStuff();
被连续调用三次 。 - 等等。
我想MethodofAnotherThreadThatChangesUIStuff();
被调用一次,不管它是哪一次点击。我的意思是,通常情况就是这样。
我在这里错过了什么?
任何帮助将非常感激。
这正在造成的,因为这条线:
exportWorker.DoWork += new DoWorkEventHandler(ExportWorkerDoWork);
正在btnOK_Click
处理程序中运行。如果你设置这样的处理程序以外的事件:
BackgroundWorker exportWorker = new BackgroundWorker();
exportWorker.DoWork += new DoWorkEventHandler(ExportWorkerDoWork);
exportWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(ExportWorkerRunWorkerCompleted);
private void btnOK_Click(object sender, RoutedEventArgs e)
{
exportWorker.RunWorkerAsync();
}
然后一切都应该像你期望的那样工作。
另一种选择实际上是在btnOK_Click
处理程序中创建一个新的BackgroundWorker
。从本质上讲,你将为每次点击创建一个新的工作者,用处理程序设置它,然后运行它。然后,您将丢弃它并为每次点击创建一个新的。
由于您在每次按下按钮时都声明了Click处理程序之外的背景,所以您需要再次添加事件处理程序。这就是为什么你的方法第二次被调用两次,第三次它会被调用三次...
要解决这个问题,请在click方法之外添加事件处理程序(例如在构造函数中),并且只留下RunAsync()调用click方法。
取消订阅事件处理程序在这种情况下并不理想,因为在取消订阅处理程序之前,该方法可能会再次开始执行...... – 2013-03-27 19:02:05
正确...错过了这个小事实。 ;) – IAbstract 2013-03-27 19:09:49
每次单击“确定”时,都会创建新的事件处理程序,这些处理程序将全部调用您的DoWork方法。
将此代码放在应用程序的初始化:
exportWorker.DoWork += new DoWorkEventHandler(ExportWorkerDoWork);
exportWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(ExportWorkerRunWorkerCompleted);
只有在您btnOK_Click
方法如下:
exportWorker.RunWorkerAsync();
也许禁用点击方法中的按钮。 – RyPope 2013-03-27 18:56:27
我看到EventHandlers的一些粗心的处理 – 2013-03-27 18:59:17