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

时间:2014-10-25 16:31:35

标签: c# wpf

问题是什么:

我有一个wpf应用程序,有一个功能"安装"分配给一个按钮。它复制并删除一些文件。在button_click功能中,我检查是否"安装"可以运行,如果可以,我可以运行它。这个函数在另一个类中,所以我通过以下方式运行它:

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&lt; - 这里看起来好多了

1 个答案:

答案 0 :(得分:2)

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

与其他活动ProgressChangedRunWorkerCompleted相同。

如果要保留持久性BackgroundWorker实例,则应在初始化时将其配置一次(例如,通过在Visual Studio Designer中设置属性和事件)。如果要在每次单击按钮时重新配置它,则不应保留持久BackgroundWorker实例。

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

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

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