我是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
)完成之前留在内存中。
谢谢!
答案 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()
后立即处理它,它仍然会在它完成之前一直存在。