为什么Task.Delay()允许无限延迟?

All*_*nek 12 .net .net-4.0 task-parallel-library async-await .net-4.5

我的应用程序冻结后,我找到了事业的一个线程等待通过创建一个任务Task.Delay()(或TaskEx.Delay()在.NET 4.0中)为它提供了一个计算TimeSpan,由于一个错误,是在一次计算到TimeSpan一个TotalMilliseconds小于或等于-1和大于-2(即在-10000到-19999刻度之间的任何位置,包括在内).

看来,当你通过负TimeSpan-2毫秒或更低,该方法正确地抛出ArgumentOutOfRangeException,但是当你提供从上述的范围内的负时间跨度,它返回一个Task从未完成(通过设置底层System.Threading.TimerdueTime-1其中表示无穷大).这意味着在该任务上设置的任何延续都将永远不会执行,并且任何发生在其.Wait()上的不良线程Task将永远被阻止.

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

Joe*_*Joe 11

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

Win32 API还使用常量INFINITE = -1进行无限超时.

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

  • @AllonGuralnek,你可以做一些像`await Task.WhenAny(mainTask,Task.Delay(timeout))`.如果你将`timeout`设置为-1,那么它永远不会超时. (3认同)

meh*_*dvd 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);
}
Run Code Online (Sandbox Code Playgroud)