是否定义了创建仅由局部变量引用的BackgroundWorker对象?

时间:2017-11-17 09:30:59

标签: c# wpf

我是C#和WPF的新手。我花了几个小时阅读在线文档和示例来查看一些代码。代码子类System.Windows.Controls.Page并使用BackgroundWorker进行后台计算。

根据我的学习,在这种情况下创建BackgroundWorker对象的理想方法是使它由类成员变量引用。

如,

public class MyPage: System.Windows.Controls.Page
{   
    // Or: backgroundWorker = new System.ComponentModel.BackgroundWorker()
    private System.ComponentModel.BackgroundWorker backgroundWorker;
    ..
}

但是,正在审查的代码创建了一个局部变量引用的对象。

// Inside a class member function
if (someCondition)
{
    BackgroundWorker worker = new BackgroundWorker();
    worker.WorkerSupportsCancellation = true;
    worker.WorkerReportsProgress = true;
    worker.DoWork += new DoWorkEventHandler(DoWork1);
    worker.DoWork += new DoWorkEventHandler(DoWork2);
    worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(RunWorkerCompleted);
    worker.RunWorkerAsync(this.DataContext);
}

这个定义得很好吗? worker超出范围后,该对象是否符合GC的条件,因为它是对象的明显唯一引用?或者框架由于那些asnyc函数回调而添加了额外的引用计数?

通过"定义良好的",我的意思是工作者对象保证至少在所有回调(例如RunWorkerCompleted)完成之前留在内存中。

谢谢!

1 个答案:

答案 0 :(得分:3)

如果您调用BackgroundWorker方法,则RunWorkerAsync()不会立即符合垃圾回收条件。您可以使用WeakReference

自行确认
BackgroundWorker worker = new BackgroundWorker();
worker.WorkerSupportsCancellation = true;
worker.WorkerReportsProgress = true;
worker.DoWork += new DoWorkEventHandler(DoWork1);
worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(RunWorkerCompleted);
worker.RunWorkerAsync();

WeakReference viewModelWeakReference = new WeakReference(worker);
worker = null;
GC.Collect();
GC.WaitForPendingFinalizers();
MessageBox.Show(viewModelWeakReference.IsAlive.ToString());

即使你在调用RunWorkerAsync()后立即处理它,它仍然会在它完成之前一直存在。