【发布时间】:2011-04-13 15:40:36
【问题描述】:
我想触发一个任务在后台线程上运行。我不想等待任务完成。
在 .net 3.5 中我会这样做:
ThreadPool.QueueUserWorkItem(d => { DoSomething(); });
在 .net 4 中,建议使用 TPL。我见过推荐的常见模式是:
Task.Factory.StartNew(() => { DoSomething(); });
但是,StartNew() 方法返回一个实现IDisposable 的Task 对象。这
似乎被推荐这种模式的人忽略了。 Task.Dispose() 方法的 MSDN 文档说:
“在释放对任务的最后引用之前,始终调用 Dispose。”
在任务完成之前,您不能对任务调用 dispose,因此让主线程等待并调用 dispose 会首先破坏在后台线程上执行的点。似乎也没有任何已完成/已完成的事件可用于清理。
Task 类的 MSDN 页面对此没有评论,《Pro C#2010...》一书推荐了相同的模式,对任务处置不做评论。
我知道如果我离开它,终结器最终会捕获它,但是当我执行大量这样的 fire & forget 任务并且终结器线程不堪重负时,这会回来咬我吗?
所以我的问题是:
- 在这种情况下不调用
Dispose()在Task类上是否可以接受?如果是这样,为什么以及是否存在风险/后果? - 是否有任何文档对此进行了讨论?
- 或者是否有适当的方法来处理我错过的
Task对象? - 或者是否有其他方法可以使用 TPL 执行“即发即弃”任务?
【问题讨论】:
标签: c# .net multithreading dispose task-parallel-library