在我的应用程序冻结之后,我将原因跟踪到等待Task.Delay()
(或.NET 4.0中的TaskEx.Delay()
)创建的任务的线程,它为其提供了计算TimeSpan
由于某个错误,有时会计算TimeSpan
TotalMilliseconds
小于或等于-1
且大于-2
(即-10000到-1之间) -19999蜱,包括在内。
当您传递TimeSpan
毫秒或更低的负-2
时,该方法会正确抛出ArgumentOutOfRangeException
,但是当您从上述范围提供负TimeSpan时,它返回一个永不完成的Task
(通过将基础System.Threading.Timer
设置为-1表示无穷大的dueTime
。这意味着在该任务上设置的任何延续都将永远不会执行,并且.Wait()
上Task
上发生的任何不良线程将永远被阻止。
从未完成的Task
有什么可能的用途?有人会期望这样的回报值吗?不应将任何负值传递给.Delay()
,包括该特殊范围内的值,抛出ArgumentOutOfRangeException
?
答案 0 :(得分:9)
Timeout.Infinite或-1非常有用,这个任务将花费不确定的时间来完成,但最终会完成。
Win32 API还使用常量INFINITE = -1进行无限超时。
您通常不希望在UI线程中使用它,因为它可能会冻结UI(这似乎是您的问题)。但是在工作线程中存在有效的用例 - 例如阻止等待来自客户端的连接的服务器。
答案 1 :(得分:2)
在模拟场景中,我想确保我在Task.WhenAny()块中的代码正在处理正在等待的任务之一,我可能会模拟其他任务并使用无限延迟来确保任务。当任何人正在处理任务时,我没有模仿无限延迟。
答案 2 :(得分:0)
当我希望控制台应用程序不终止时,我正在使用它。 例如,当我为Auzre编写 Web Job 时,我需要一个永不终止的程序。这是模板:
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);
}