我在使用 System.Threading.Tasks
时很开心。然而,我看到的许多代码示例看起来像这样:
Dim lcTask = Task.Factory.StartNew(Sub() DoSomeWork())
Dim lcTaskLong = Task.Factory.StartNew(Sub() DoSomeWork(), TaskCreationOptions.LongRunning)
Task.WaitAll(lcTask, lcTaskLong)
这就是样本的范围。
任务实现了 IDisposable
,所以显然我应该处理掉它们,但是如果我只想“发射后不管”怎么办?
如果我不处置,我会泄漏线程/句柄/内存/业力吗? 我使用的任务是“错误的”吗? (应该只使用委托(delegate)并单独留下任务吗?)
我可以在 ContinueWith()
中处理吗? (这就像玩俄罗斯轮盘赌一样。)
最佳答案
虽然通常的经验法则是始终调用 Dispose()
在所有IDisposable
实现,Task
和 Task<T>
通常情况下,最好让终结器来处理这个问题。
Task 执行 IDisposable
的原因主要是由于内部的 WaitHandle。这是允许任务延续正常工作所必需的,并且仅在任务有延续时使用。如果没有继续,Task 的 Dispose 方法没有实际效果 - 因此在这种情况下,它不是必需的。
话虽这么说,在大多数情况下有任务延续,通常很难以允许您正确调用 Dispose() 的方式编写代码。 using 语句通常不适用于 Task 实例,因为 Task 调用本质上通常是异步的。过早地处理 Task 非常容易,尤其是在使用 using 语句时。
如果在您的情况下,保留对 Task 的引用并正确调用 Dispose() 相对简单,我会这样做。但是,如果这会导致您的逻辑变得更加复杂,我通常会假装 Task 不是 IDisposable
。 ,并允许它在任务的终结器中被清理。
有关更多详细信息,我建议 reading this thread on the MSDN forums其中 Stephen Toub 详细描述了 Task 实现 IDisposable 的原因,并提供了与我上面的建议类似的指导。
关于.net - 我需要处理任务吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49106756/