Ric*_*ckL 32 c# dispose backgroundworker
我通常在表单上有这样的代码:
private void PerformLongRunningOperation()
{
BackgroundWorker worker = new BackgroundWorker();
worker.DoWork += delegate
{
// perform long running operation here
};
worker.RunWorkerAsync();
}
Run Code Online (Sandbox Code Playgroud)
这意味着我不会处理它BackgroundWorker,而如果我已经由表单设计者添加它,那么我认为它会被处理掉.
这会导致任何问题吗?声明模块级别_saveWorker,然后Dispose从表单的dispose方法调用它更正确吗?
Sim*_*ens 32
是的,你应该处理后台工作人员.
您可能会发现它更容易使用ThreadPool.QueueUserWorkItem(...),之后不需要任何清理.
有关为何应始终调用Dispose()的其他详细信息:
虽然如果查看BackgroundWorker类,它实际上并没有在它的dispose方法中进行任何线程清理,但由于该类对垃圾收集器的影响,调用Dispose仍然很重要.
具有终结器的类不会立即进行GC.它们被保留并添加到终结器队列中.然后运行终结器线程(遵循标准模式调用dispose).这意味着该对象将继续存在于GC生成1中.而第1代集合远比gen 0集合更少,因此您可以在内存中反复使用更长时间.
但是,如果您调用Dispose(),则该对象将不会添加到终结队列中,因此可以自由地进行垃圾回收.
这不是什么大问题,但是如果你创造了很多它们,你最终会使用比必要更多的内存.始终在具有dispose方法的对象上调用dispose应该被认为是一种好习惯.
所以我想,总而言之,这不是100%的硬性和快速要求.如果您不调用Dispose(),您的应用程序将不会爆炸(甚至泄漏内存),但在某些情况下,它可能会产生负面影响.后台工作程序设计为可以作为WinForms组件使用,所以如果你有不同的要求并且不想将它用作WinForms组件,请不要使用它,使用正确的工具,像ThreadPool一样.
Nei*_*ell 16
挑战在于确保只BackgroundWorker 在完成运行后才处理掉.您无法在Completed事件中执行此操作,因为该事件由BackgroundWorker本身引发.
BackgroundWorker真的打算用作WinForms表单上的一个组件,所以我建议你这样做,或者切换到类似的东西Thread.QueueUserWorkItem.这将使用线程池线程,并且在完成时不需要任何特殊清理.
在我看来,一般来说,如果它是IDisposable,那么当你完成它时它应该是Dispose()d.即使在技术上不需要处理BackgroundWorker的当前实现,您也不希望后来的内部实现感到惊讶.
我不会打扰,Bgw可以保留的唯一资源是Thread,如果你的代表中没有无限循环那么你很好.
BackgroundWorker继承IDisposable()自Component,但并不真正需要它.
将它与直接在ThreadPool上推送方法进行比较.你没有(不能)Dispose线程,当然不是来自Pool的线程.
但是如果你的样本是完整的,你没有使用Completed事件或Progress/Cancel功能,你也可以使用ThreadPool.QueueUserWorkItem().