【发布时间】:2012-05-31 06:17:43
【问题描述】:
在我的应用程序冻结后,我追踪了一个线程等待由Task.Delay()(或.NET 4.0 中的TaskEx.Delay())创建的任务的原因,它提供了一个计算的TimeSpan,由于一个错误,有时被计算为TimeSpan,其中TotalMilliseconds 小于或等于-1 且大于-2(即介于-10000 到-19999 滴答之间的任意值,包括)。
看来,当您传递一个负数 TimeSpan(即 -2 毫秒或更低)时,该方法会正确地抛出一个 ArgumentOutOfRangeException,但是当您提供上述范围内的负 TimeSpan 时,它会返回一个 @987654331 @ 永远不会完成(通过将基础 System.Threading.Timer 设置为 -1 的 dueTime 表示无穷大)。这意味着在该任务上设置的任何延续都将永远不会执行,并且在该Task 上发生在.Wait() 上的任何不良线程将永远被阻止。
永远不会完成的Task 有什么可能的用途?有人会期望这样的返回值吗?是否应该将任何负值传递给.Delay(),包括该特殊范围内的值,抛出ArgumentOutOfRangeException?
【问题讨论】:
-
MSDN 文档非常明确地允许 -1,因此它的行为似乎正确。不确定该重载的用例,但它可能是一种等待“只是”取消带有取消令牌的重载的方法。
-
@James:允许 -1 并不明确,但不允许低于 -1 的值是明确的。与
System.Threading.Timer的文档不同,它甚至没有说明如果通过 -1 会发生什么。几乎看起来记录的异常列表是从源代码自动生成的。如果您正在等待“只是”取消,为什么还要打电话给Task.Delay()? -
如果您认为它已损坏,请在连接时提交错误。一个说“低于 -1 无效”的文档(对我来说)明确表示 -1 是有效的。如果意图是 -1 无效,“低于 0 无效”会更容易编写。由于文档和代码都允许-1,我认为这是设计使然,但请随时在连接上提交错误(我认为 BCL 团队更有可能处理而不是随机 SO 线程 :)
-
@James:我在 SO 上发布它的原因是因为我不确定这是一个错误。我正在寻找这个 API 设计的解释,假设它是故意的。例如,svick 的用例是有意义的。
标签: .net .net-4.0 task-parallel-library .net-4.5 async-await