我需要处置任务吗?

问题描述 投票:0回答:1

我和

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()
吗? (这看起来就像玩俄罗斯轮盘赌。)

.net task-parallel-library dispose
1个回答
22
投票

虽然正常的经验法则是始终在所有

Dispose()
实现上调用
IDisposable
,但
Task
Task<T>
通常是最好让终结器处理此问题的一种情况。

Task 实现

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

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

如果在您的情况下,保留对任务的引用并正确调用 Dispose() 相对简单,我会这样做。但是,如果这会导致您的逻辑变得更加复杂,我通常会假装 Task 不是

IDisposable
,并允许在 Task 的终结器中清理它。

有关更多详细信息,我建议阅读 MSDN 论坛上的此帖子,其中 Stephen Toub 详细描述了 Task 实现 IDisposable 的原因,并提供了与我上面的建议类似的指导。

© www.soinside.com 2019 - 2024. All rights reserved.