Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# BackgroundWorker每运行n次就工作n次_C#_Wpf - Fatal编程技术网

C# BackgroundWorker每运行n次就工作n次

C# BackgroundWorker每运行n次就工作n次,c#,wpf,C#,Wpf,问题是: 我有一个wpf应用程序,其中一个功能“安装”分配给一个按钮。它复制和删除一些文件。在按钮单击功能中,我正在检查“安装”是否可以运行,如果可以,我正在运行它。此函数位于另一个类中,因此我通过以下方式运行它: class1 class = new class1(); class.function(); 其功能是: public void install() { worker.RunWorkerAsync(); worker.WorkerSupportsCancellati

问题是:

我有一个wpf应用程序,其中一个功能“安装”分配给一个按钮。它复制和删除一些文件。在按钮单击功能中,我正在检查“安装”是否可以运行,如果可以,我正在运行它。此函数位于另一个类中,因此我通过以下方式运行它:

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
    };
 }
public void安装()
{
worker.RunWorkerAsync();
worker.worker支持扫描单元=true;
worker.WorkerReportsProgress=true;
worker.DoWork+=(s,args)=>
{
对于(int i=0;i
{
//报告进展
};
worker.RunWorkerCompleted+=(s,args)=>
{
worker.CancelAsync();//不确定是否需要它,它不会更改任何内容
//重置一些值
};
}
是的,类似的。如果它看起来有点迟钝,很抱歉,但我是新来的,仍然在学习如何粘贴代码元素:p(如果需要,我可以上传整个项目或粘贴某些部分)

整个过程运行良好,但当我在第2次、第3次、第n次单击安装按钮时,工作人员正在做它的工作n次(参见线程名称)。我不知道为什么。 我是不是错过了worker.close()之类的东西


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

同样,其他事件,
ProgressChanged
RunWorkerCompleted

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

例如,俗气的方法是在
install()
方法的开头添加以下内容:

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

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

在您的安装方法中,执行worker.IsBusy检查以防止多次运行,“全部完成”弹出窗口应位于worker completed中,并且在工作完成后,您不需要取消异步。您能向我解释我应该做什么吗?我在wpf中有点不知所措:(请参阅我编辑过的答案。不幸的是,很难描述最好的方法,因为我不知道您首先是如何声明BackgroundWorker的。但是如果您可以在designer中配置它一次,那将是最好的。嘿。感谢您的帮助,但我仍然在做错事。无论如何,我已经完成了一个新项目只使用这一个函数来确保问题只存在于backgroundworker。是的,的确如此。在这里,我将visual studio 2013项目打包到一个zip文件中,所以如果您可以看一下:)您好。我没有看您的下载链接。我的答案中的说明对我来说非常清楚:只需在我指定的位置添加我显示的代码。这可能不是修复程序的最漂亮的方法,但它可以完成工作。有一天,当您学会使用VS GUI设计工具时,一个灯泡就会亮起来,您就会明白我的意思t关于在设计工具中配置
BackgroundWorker
一次,而不是每次要在运行时运行
BackgroundWorker
时都重新配置。