取消订阅RunWorkerCompleted?

时间:2014-06-19 19:56:13

标签: c# winforms

我有以下功能,我想在完成后取消订阅RunWorkerCompleted(以防止内存泄漏)。但是我得到了错误"使用未分配的本地变量' runWorkerCompleted'"

private void Assign<T>(Func<object> method, Action<T> setter)
{
    ShowLoadingLabel();
    var bw = new BackgroundWorker();
    DoWorkEventHandler doWork = (object sender, DoWorkEventArgs e) => e.Result = ((Func<object>)(e.Argument))();
    bw.DoWork += doWork;
    RunWorkerCompletedEventHandler runWorkerCompleted = (object sender, RunWorkerCompletedEventArgs e) =>
    {
        setter((T)e.Result);
        HideLoadingLabel();
        bw.DoWork -= doWork;
        bw.RunWorkerCompleted -= runWorkerCompleted; // Error
    };
    bw.RunWorkerCompleted += runWorkerCompleted;
    bw.RunWorkerAsync(method);
}

如何取消订阅?

3 个答案:

答案 0 :(得分:2)

要使处理程序自行删除,您需要遵循以下通用模板:

DelegateType handler = null;

handler = ()=>
{
    DoOtherStuff();
    someObject.SomeEvent -= handler;
};

someObject.SomeEvent += handler;

答案 1 :(得分:2)

你不能在同一行中分配和使用(技术上仍然是初始化行。只需将你的行分成两行。

private void Assign<T>(Func<object> method, Action<T> setter)
{
    ShowLoadingLabel();
    var bw = new BackgroundWorker();
    DoWorkEventHandler doWork = (object sender, DoWorkEventArgs e) => e.Result = ((Func<object>)(e.Argument))();
    bw.DoWork += doWork;
    RunWorkerCompletedEventHandler runWorkerCompleted = null;
    runWorkerCompleted = (object sender, RunWorkerCompletedEventArgs e) =>
    {
        setter((T)e.Result);
        HideLoadingLabel();
        bw.DoWork -= doWork;
        bw.RunWorkerCompleted -= runWorkerCompleted; // Error
    };
    bw.RunWorkerCompleted += runWorkerCompleted;
    bw.RunWorkerAsync(method);

但是我认为所有这些都是unessesary,因为bw超出了函数末尾的范围,因此没有任何东西支持你的委托,所以没有内存泄漏。

答案 2 :(得分:1)

您获得的错误是&#34;用于未分配的本地变量&#34;要解决此问题,请将runworkerCompleted初始化为null,然后为其指定一个值,如:

RunWorkerCompletedEventHandler runWorkerCompleted = null;
runWorkerCompleted = (object sender, RunWorkerCompletedEventArgs e) =>
{
    setter((T)e.Result);
    HideLoadingLabel();
    bw.DoWork -= doWork;
    bw.RunWorkerCompleted -= runWorkerCompleted; // Error
};