我想触发一个在后台线程上运行的任务.我不想等待任务完成.

在里面net 3.5我会这样做:

ThreadPool.QueueUserWorkItem(d => { DoSomething(); });

在.NET4中,建议使用TPL.我看到推荐的常见模式是:

Task.Factory.StartNew(() => { DoSomething(); });

然而,StartNew()方法返回一个Task对象,它实现IDisposable.这

"在释放对任务的最后引用之前,请始终调用Dispose."

在任务完成之前不能对其调用Dispose,因此让主线程等待并调用Dispose首先会 destruct 对后台线程执行操作的意义.似乎也没有任何已完成/已完成事件可用于清理.

Task类上的MSDN页面没有对此进行 comments ,还有《Pro C#2010推荐相同的模式,对任务处理不做 comments .

我知道如果我把它放在一边,终结器最终会抓住它,但是当我做很多火的时候,它会回来咬我吗?忘掉像这样的任务,终结器线程会不堪重负吗?

所以我的问题是:

  • 在这种情况下,Task班不打Dispose()分可以接受吗?如果是,为什么会有风险/后果?
  • 是否有任何文档对此进行了讨论?
  • 或者有没有合适的方法来处理我错过的Task件物品?
  • 还是有其他的方法来灭火;忘记TPL的任务?

推荐答案

有一个关于这in the MSDN forums的讨论.

微软PFX团队成员斯蒂芬·图布(Stephen Toub)说:

Task.Dispose exists due to Task potentially wrapping an event handle used when waiting on the task to complete, in the event the waiting thread actually has to block (as opposed to spinning or potentially executing the task it's waiting on). If all you're doing is using continuations, that event handle will never be allocated
...
it's likely better to rely on finalization to take care of things.

Update (Oct 2012)
Stephen Toub has posted a blog titled Do I need to dispose of Tasks? which gives some more detail, and explains the improvements in .Net 4.5.

总之:99%的时间里你不需要处理Task件物品.

处置对象有两个主要原因:以及时、确定的方式释放非托管资源,以及避免运行对象的终结器的成本.在大多数情况下,这两种情况都不适用于Task:

  1. 截至.Net 4.5中,Task唯一分配内部等待句柄(Task对象中唯一的非托管资源)的时间是显式使用Task中的IAsyncResult.AsyncWaitHandle,并且
  2. Task对象本身没有终结器;句柄本身包装在带有终结器的对象中,所以除非分配了终结器,否则没有终结器要运行.

.net相关问答推荐

在PowerShell中,XML子对象和属性是对象属性.它怎麽工作?

EF Core IEntityTypeConfigurations:从数据库提取数据后相关对象为空

如何使用 awslocal 通过 localstack 中的 cloudwatch events/eventbridge 触发 lambda

Silverlight 与 Flex

使用返回随机结果的函数进行单元测试

我可以使用 UriTemplate 将非字符串传递给 WCF RESTful 服务吗?

如何将 UI Dispatcher 传递给 ViewModel

如何遍历字典并更改值?

为什么 .NET 中不需要 Maven?

为什么使用 ImmutableList 而不是 ReadOnlyCollection?

Double.TryParse 或 Convert.ToDouble - 哪个更快更安全?

如何在 WPF 中的 Xaml 文件中添加注释?

实体框架中的 POCO 是什么?

判断 .NET 中的目录和文件写入权限

具有不同身份验证标头的 HttpClient 单个实例

如果选中,则更改列表框项的 WPF DataTemplate

表单不响应 KeyDown 事件

如何隐藏 WPF ListView 的标题?

模拟和单元测试需要时如何抛出 SqlException?

序列化一个可为空的 int