我可以在方法中定义后台工作程序吗?
private void DownLoadFile(string fileLocation){
BackgroundWorker worker = new BackgroundWorker();
worker.DoWork += new DoWorkEventHandler((obj, args) => {
// Will be executed by back ground thread asynchronously.
args.Result = Download(fileLocation);
});
worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler((obj, args) => {
// will be executed in the main thread.
Result r = args.Result as Result;
ReportResult(r);
});
worker.RunWorkerAsync(fileLocation);
}
问题:如果Download()函数需要很长时间才能下载文件,那么GC可以在执行RunWorkerCompleted()之前启动并收集worker对象吗?
答案 0 :(得分:12)
鉴于您实际上没有使用BackgroundWorker的大部分功能,我建议使用TPL代替:
private void DownLoadFile(string fileLocation)
{
Task.Factory.StartNew( () => Download(fileLocation))
.ContinueWith(t => ReportResult(t.Result), TaskScheduler.FromCurrentSynchronizationContext());
}
话虽这么说,worker
对象一旦运行就不会被垃圾收集,因为ThreadPool线程本身会将worker保持为“used object”。垃圾收集器将在完成事件处理程序执行之后才能收集它,此时将不会有用户代码可以到达BackgroundWorker
的实例。
此外,它可能会使此类的实例不被垃圾收集,因为闭包使用的实例方法(ReportResults
)使“this”实例可以访问且不符合GC的条件。< / p>