2011-05-13 89 views
17

我很开心与System.Threading.Tasks一起工作。然而,我看到的许多代码示例看起来像这样:我是否需要处置任务?

Dim lcTask = Task.Factory.StartNew(Sub() DoSomeWork()) 
Dim lcTaskLong = Task.Factory.StartNew(Sub() DoSomeWork(), TaskCreationOptions.LongRunning) 
Task.WaitAll(lcTask, lcTaskLong) 

这就是样本的范围。
任务执行IDisposable,所以显然我应该把它们处理掉,但是如果我只是想“火与忘”呢?

如果我不处理,我会泄漏线程/句柄/内存/业障吗? 我是否在使用任务“错误”? (应该只是使用委托并单独留下任务?)

我可以在ContinueWith()中处理吗? (这似乎是玩俄罗斯轮盘赌。)

回答

18

虽然拇指的正常规则是随时拨打Dispose()所有IDisposable实现,TaskTask<T>往往是一个情况下,最好让终结照顾这。

Task执行IDisposable的原因主要是由于内部的WaitHandle。这是允许任务继续正常工作所必需的,并且只有在任务继续时才能使用。如果没有延续,任务的Dispose方法没有实际效果 - 所以在这种情况下,这不是必需的。

这就是说,在大多数情况下,如果存在任务延续,那么以正确调用Dispose()的方式编写代码通常非常非常困难。使用语句通常不适用于Task实例,因为Task调用本质上通常是异步的。很容易过早地处理该任务,特别是在使用using语句时。

如果在您的情况下,保持对任务的引用并正确调用Dispose()相对简单,我会这样做。但是,如果这会导致您的逻辑变得复杂得多,我通常会假装Task不是IDisposable,并允许在任务的终结器中清理它。

欲了解更多详情,我建议reading this thread on the MSDN forums其中Stephen Toub描述了Task为什么实现IDisposable的细节,并提供了与上述建议类似的指导。

+1

And ... \t \t [CodeAnalysis.SuppressMessage(“Microsoft.Reliability”,“CA2000”,Justification =“http://stackoverflow.com/questions/5985973/do-i-need-to-dispose-of -a-task“)] – GarethOwen 2012-06-18 15:03:18

+2

根据您链接到的Stephen Toub线程判断,我认为当您说”需要[等待句柄]以允许任务继续正常工作并且仅在存在如果没有延续,任务的Dispose方法没有实际效果......“但根据Toub的说法,”Task.Dispose的存在是由于任务可能包装了一个事件句柄......如果你正在做的正在使用continuation,那个事件句柄永远不会被分配,并且Dispose的值会大大减少。“即与上面暗示的相反。 – 2015-09-06 19:14:58

相关问题