2013-03-27 155 views
2

这是我的代码。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();被调用一次,不管它是哪一次点击。我的意思是,通常情况就是这样。

我在这里错过了什么?

任何帮助将非常感激。

+0

也许禁用点击方法中的按钮。 – RyPope 2013-03-27 18:56:27

+0

我看到EventHandlers的一些粗心的处理 – 2013-03-27 18:59:17

回答

2

这正在造成的,因为这条线:

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。从本质上讲,你将为每次点击创建一个新的工作者,用处理程序设置它,然后运行它。然后,您将丢弃它并为每次点击创建一个新的。

9

由于您在每次按下按钮时都声明了Click处理程序之外的背景,所以您需要再次添加事件处理程序。这就是为什么你的方法第二次被调用两次,第三次它会被调用三次...

要解决这个问题,请在click方法之外添加事件处理程序(例如在构造函数中),并且只留下RunAsync()调用click方法。

+0

取消订阅事件处理程序在这种情况下并不理想,因为在取消订阅处理程序之前,该方法可能会再次开始执行...... – 2013-03-27 19:02:05

+0

正确...错过了这个小事实。 ;) – IAbstract 2013-03-27 19:09:49

3

每次单击“确定”时,都会创建新的事件处理程序,这些处理程序将全部调用您的DoWork方法。

将此代码放在应用程序的初始化:

exportWorker.DoWork += new DoWorkEventHandler(ExportWorkerDoWork); 
exportWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(ExportWorkerRunWorkerCompleted); 

只有在您btnOK_Click方法如下:

exportWorker.RunWorkerAsync();