我想触发任务在后台线程上运行。我不想等待任务完成。
在.net 3.5中,我应该这样做:
ThreadPool.QueueUserWorkItem(d => { DoSomething(); });
在.net 4中,建议使用TPL。我看到的推荐的常见模式是:
Task.Factory.StartNew(() => { DoSomething(); });
但是,该StartNew()
方法返回一个Task
实现的对象IDisposable
。推荐这种模式的人似乎忽略了这一点。有关该Task.Dispose()
方法的MSDN文档说:
“在释放对任务的最后引用之前,请始终致电Dispose。”
您不能在任务完成之前对其进行调用处置,因此让主线程等待并进行调用处置首先会破坏在后台线程上执行任务的目的。似乎也没有任何可用于清理的完成/完成事件。
Task类的MSDN页面没有对此发表评论,而《 Pro C#2010 ...》这本书推荐了相同的模式,并且对任务处理没有评论。
我知道如果我只留下它,终结器最终会抓住它,但是当我做很多工作而忘了像这样的任务而终结器线程不堪重负时,这会回来咬我吗?
所以我的问题是:
- 是否可以接受不叫
Dispose()
就Task
在这种情况下类?如果是这样,为什么而且存在风险/后果? - 有没有讨论这个的文档?
- 还是有适当的方法来处理
Task
我错过的对象? - 还是有另一种通过TPL做事忘了任务的方法?