I want to wait for a Task<T> to complete with some special rules: If it hasn't completed after X milliseconds, I want to display a message to the user. And if it hasn't completed after Y milliseconds, I want to automatically request cancellation.

I can use Task.ContinueWith to asynchronously wait for the task to complete (i.e. schedule an action to be executed when the task is complete), but that doesn't allow to specify a timeout. I can use Task.Wait to synchronously wait for the task to complete with a timeout, but that blocks my thread. How can I asynchronously wait for the task to complete with a timeout?

推荐答案

这个怎么样:

int timeout = 1000;
var task = SomeOperationAsync();
if (await Task.WhenAny(task, Task.Delay(timeout)) == task) {
    // task completed within timeout
} else { 
    // timeout logic
}

这是a great blog post "Crafting a Task.TimeoutAfter Method" (from MS Parallel Library team) with more info on this sort of thing美元.

Addition:应我的回答的要求,这里有一个扩展的解决方案,包括取消处理.请注意,将取消传递给任务和计时器意味着代码中有多种方式可以经历取消,您应该确保测试并确信您正确处理了所有这些方式.不要让你的计算机在运行时做正确的事情,而go try 各种组合.

int timeout = 1000;
var task = SomeOperationAsync(cancellationToken);
if (await Task.WhenAny(task, Task.Delay(timeout, cancellationToken)) == task)
{
    // Task completed within timeout.
    // Consider that the task may have faulted or been canceled.
    // We re-await the task so that any exceptions/cancellation is rethrown.
    await task;

}
else
{
    // timeout/cancellation logic
}

.net相关问答推荐

Erlang 的让它崩溃的哲学 - 适用于其他地方吗?

为什么这两个比较有不同的结果?

移位比Java中的乘法和除法更快吗? .网?

在 .NET 中获取执行 exe 路径的最佳方法是什么?

.NET 的 Visual Studio 调试器提示和技巧

.Include() 与 .Load() 在 EntityFramework 中的性能

如何中止任务,如中止线程(Thread.Abort 方法)?

我可以从我的应用程序中抛出哪些内置 .NET 异常?

SubscribeOn 和 ObserveOn 有什么区别

为什么需要 XmlNamespaceManager?

将 Topshelf 应用程序安装为 Windows 服务

如何将 UI Dispatcher 传递给 ViewModel

关于 Enumerable.Range 与传统 for 循环的 foreach 的思考

在未安装 Visual Studio 的机器上使用 FUSLOGVW.EXE

Iif 在 C# 中等效

为什么 C# 不推断我的泛型类型?

我应该绑定到 ICollectionView 还是 ObservableCollection

如何从文件中删除单个属性(例如只读)?

如何为我的 C# 应用程序创建产品密钥?

为什么 IList 不支持 AddRange