处理BackGroundWorker的正确方法

时间:2010-03-30 01:36:10

标签: c# .net multithreading backgroundworker

这是处理BackGroundWorker的正确方法吗?我不确定在调用.Dispose()之前是否需要删除事件。还在RunWorkerCompleted委托中调用.Dispose()确定吗?

public void RunProcessAsync(DateTime dumpDate)
{
    BackgroundWorker worker = new BackgroundWorker();
    worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(worker_RunWorkerCompleted);
    worker.DoWork += new DoWorkEventHandler(worker_DoWork);
    worker.RunWorkerAsync(dumpDate);
}

void worker_DoWork(object sender, DoWorkEventArgs e)
{
    // Do Work here
}

void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    BackgroundWorker worker = sender as BackgroundWorker;
    worker.RunWorkerCompleted -= new RunWorkerCompletedEventHandler(worker_RunWorkerCompleted);
    worker.DoWork -= new DoWorkEventHandler(worker_DoWork);
    worker.Dispose();
}

5 个答案:

答案 0 :(得分:69)

BackgroundWorker派生自Component。 Component实现了IDisposable接口。这反过来使BackgroundWorker继承了Dispose()方法。

从Component派生是Windows Forms程序员的便利,他们可以将BGW从工具箱中删除到表单上。一般来说,组件可能有某些东西需要处理。 Windows窗体设计器自动处理此问题,在Designer.cs文件中查找“components”字段的Form。它的自动生成的Dispose()方法为所有组件调用Dispose()方法。

但是,BackgroundWorker实际上并没有任何需要处理的成员。它不会覆盖Dispose()。它的基本实现Component.Dispose()只确保从“components”集合中删除该组件。并提出Disposed事件。但是没有其他任何处理。

长话短说:如果你在表格上放弃一个BGW,那么一切都会自动处理,你无需帮助。如果你没有将它放在表单上,​​那么它就不是组件集合中的元素,也不需要做任何事情。

您不必调用Dispose()

答案 1 :(得分:13)

游戏的后期,但我刚遇到了与我的问题相关的情景,我认为我会分享。如果您在类级别创建工作程序并在不关闭应用程序的情况下在连续操作中重复使用它,如果在完成后不删除事件,则每次连续执行时它们将递增并运行多次。

worker.RunWorkerCompleted -= new RunWorkerCompletedEventHandler(worker_RunWorkerCompleted);
worker.DoWork -= new DoWorkEventHandler(worker_DoWork);

如果没有上述我的DoWork第一次触发,第二次触发两次,等等。对于大多数人来说,这可能是一个明智的选择,但是我花了一些时间才弄明白,所以希望这会帮助其他人

答案 2 :(得分:1)

worker.Dispose()不是必需的,因为会自动调用Dispose()。但在处理对象之前,您需要删除所有事件处理程序。

article告知了我们。

worker.RunWorkerCompleted -= new RunWorkerCompletedEventHandle(worker_RunWorkerCompleted);
worker.DoWork -= new DoWorkEventHandler(worker_DoWork);

答案 3 :(得分:0)

是的,这似乎是正确的。当然,使用using块可以更好地处理一次性对象,但是这里没有这个选项。

我通常使用表单生命周期创建我的后台处理程序,重用它们,并让设计器代码处理表单上的处理。少考虑一下。

答案 4 :(得分:0)

如果它位于“WinForms”表单上,请让容器处理它(请参阅Form.Designer.xyz文件中生成的Dispose代码)

在实践中,我发现您可能需要创建容器的实例并将工作者(或其他组件)添加到其中,如果有人知道更正式的方法,请大声说出来!

PK: - )

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();

        // watch the disposed event....
        backgroundWorker1.Disposed += new EventHandler(backgroundWorker1_Disposed);

        // try with and without the following lines
        components = new Container();
        components.Add(backgroundWorker1);
    }

    void backgroundWorker1_Disposed(object sender, EventArgs e)
    {
        Debug.WriteLine("backgroundWorker1_Disposed");
    }

//... from the Designer.xyz file ...

    /// <summary>
    /// Clean up any resources being used.
    /// </summary>
    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
    protected override void Dispose(bool disposing)
    {
        if (disposing && (components != null))
        {
            components.Dispose();
        }
        base.Dispose(disposing);
    }

}