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<-在这里,它看起来更好

BackgroundWorker每运行n次就要工作n次

每次处理按钮单击时,都会将工作方法订阅到DoWork事件。在C#中,委托是"多播"的,这意味着它们可以有多个调用目标。每次订阅工作者方法时,都会添加一个调用目标,从而导致该方法被额外调用一次。因此,对于N次按下按钮,您将在DoWork事件委托中获得相同调用目标方法的N个副本。

类似地,其它事件ProgressChangedRunWorkerCompleted

如果要保留一个持久的BackgroundWorker实例,则应在初始化它时仅对其进行一次配置(例如,通过在Visual Studio设计器中设置属性和事件)。如果您想在每次单击按钮时重新配置它,那么不应该保留持久的BackgroundWorker实例。

例如,俗气的方法,将其添加到install()方法的开头:

if (worker != null)
{
    worker.Dispose();
}
worker = new BackgroundWorker();

非俗气的方法包括找到BackgroundWorker对象的初始化,并将所有初始化都放在那里。我不知道这是如何在WPF设计器UI中显示的。。。在Forms中,您可以在所有者窗体的设计窗口底部获得BackgroundWorker组件;您可以单击该组件,然后通过"属性"窗口编辑属性和事件处理程序。