17

在我的应用程序冻结后,我追踪了一个线程等待由Task.Delay()(或TaskEx.Delay()在 .NET 4.0 中)创建的任务的原因,它为其提供了一个计算TimeSpan,由于错误,有时计算为 aTimeSpan小于TotalMilliseconds或等于-1和大于-2(即介于 -10000 到 -19999 个刻度之间的任意位置,包括端点)。

看来,当您传递一个毫秒或更低的负数时,该TimeSpan方法正确地-2抛出一个表示无穷大)。这意味着该任务上设置的任何延续将永远不会执行,并且发生在该任务上的任何不良线程将永远被阻止。ArgumentOutOfRangeExceptionTaskSystem.Threading.TimerdueTime.Wait()Task

Task一个永远不会完成的东西有什么可能的用途?有人会期望这样的返回值吗?传递给 的任何负值.Delay()(包括该特殊范围内的值)不应该抛出一个ArgumentOutOfRangeException?

4

3 回答 3

17

Timeout.Infinite或 -1 在您想无限期地等待一个长时间运行的任务时很有用,该任务将花费不确定的时间来完成,但最终会完成。

Win32 API 还使用常量 INFINITE = -1 来表示无限超时。

您通常不想在 UI 线程中使用它,因为它可能会冻结 UI(这似乎是您的问题)。但是在工作线程中有一些有效的用例——例如,服务器阻塞等待来自客户端的连接。

于 2012-05-24T17:26:05.117 回答
7

当我希望控制台应用程序不终止时,我正在使用它。例如,当我为 Azure 编写Web 作业时,我需要一个永不终止的程序。这是模板:

public async Task Main(string args[])
{
    var timer = new Timer();
    timer.Interval = 6000;
    timer.Elapsed += (sender, args) =>
    {
        // Do something repeatedly, each 1 minute.
    };
    timer.Start();

    // Now what to do to stop the application from terminating!?
    // That's the magic:
    await Task.Delay(-1);
}
于 2019-02-11T09:46:55.080 回答
2

在模拟场景中,我想确保 Task.WhenAny() 块中的代码正确处理等待的任务之一,我可以模拟其他任务并使用无限延迟来确保 Task.WhenAny 正在处理我没有将任务嘲笑为无限延迟。

于 2015-11-25T23:32:35.140 回答