我需要处理任务吗?

时间:2011-05-13 00:14:49

标签: .net task-parallel-library dispose

我很高兴与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()吗? (这好像在玩俄罗斯轮盘赌。)

1 个答案:

答案 0 :(得分:18)

虽然通常的经验法则是始终在所有Dispose()实施中调用IDisposable,但TaskTask<T>通常是一种情况,最好让终结者采取行动照顾这个。

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

话虽如此,在大多数情况下,如果有任务延续,通常非常非常难以以允许您正确调用Dispose()的方式编写代码。使用语句通常不适用于Task实例,因为Task调用本质上通常是异步的。过早地处理Task非常容易,尤其是在使用using语句时。

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

有关详细信息,我建议使用reading this thread on the MSDN forums,其中Stephen Toub描述了Task为何详细实现了IDisposable,并为我上面的建议提供了类似的指导。