BackgroundWorker每运行n次就要工作n次
本文关键字:工作 BackgroundWorker 运行 | 更新日期: 2023-09-27 18:27:59
问题出在哪里:
我有一个wpf应用程序,有一个功能"安装"分配给一个按钮。它复制和删除一些文件。在button_click函数中,我检查"install"是否可以运行,如果可以,我正在运行它。这个函数在另一个类中,所以我运行它的方式是:
class1 class = new class1();
class.function();
功能是:
public void install()
{
worker.RunWorkerAsync();
worker.WorkerSupportsCancellation = true;
worker.WorkerReportsProgress = true;
worker.DoWork += (s, args) =>
{
for(int i=0;i<100;i++)
{
//do some work;
worker.ReportProgress(i);
}
MessageBox.Show("done");
};
worker.ProgressChanged += (s, args) =>
{
// report progress
};
worker.RunWorkerCompleted += (s, args) =>
{
worker.CancelAsync(); //not sure if it's needed, it changes nothing
//reset some values
};
}
是的,差不多吧。很抱歉,如果它看起来有点迟钝,但我是新来的,仍在学习如何粘贴代码元素:P(如果需要,我可以上传整个项目或粘贴一些部分)
整件事都很好,但当我点击第二、第三、…的安装按钮时。。。,第n次工作人员执行其工作n次(请参见线程名称)。我不知道为什么。我是不是错过了worker.close()之类的东西?
编辑:http://pastebin.com/YR9ZHCCY<-在这里,它看起来更好
每次处理按钮单击时,都会将工作方法订阅到DoWork
事件。在C#中,委托是"多播"的,这意味着它们可以有多个调用目标。每次订阅工作者方法时,都会添加一个调用目标,从而导致该方法被额外调用一次。因此,对于N次按下按钮,您将在DoWork
事件委托中获得相同调用目标方法的N个副本。
类似地,其它事件ProgressChanged
和RunWorkerCompleted
。
如果要保留一个持久的BackgroundWorker
实例,则应在初始化它时仅对其进行一次配置(例如,通过在Visual Studio设计器中设置属性和事件)。如果您想在每次单击按钮时重新配置它,那么不应该保留持久的BackgroundWorker
实例。
例如,俗气的方法,将其添加到install()
方法的开头:
if (worker != null)
{
worker.Dispose();
}
worker = new BackgroundWorker();
非俗气的方法包括找到BackgroundWorker对象的初始化,并将所有初始化都放在那里。我不知道这是如何在WPF设计器UI中显示的。。。在Forms中,您可以在所有者窗体的设计窗口底部获得BackgroundWorker组件;您可以单击该组件,然后通过"属性"窗口编辑属性和事件处理程序。