我需要在移动应用程序中的任务调用中添加超时功能。我尝试使用Task.WhenAny来完成此操作,如下所示。
首先,您应该知道,如果不将CancellationToken传递给GetRequestAsync,则实际上不会取消请求。它将继续处理。
其次,我发现您的代码相当奇怪,因为在其当前状态下有两个可能的超时:Task.Delay可能会完成,或者CancellationToken可能会被标记。其中一个(Task.Delay)是正常任务完成,而另一个(CancellationToken)是真正的取消。
如果CancellationToken是您的超时,则可以使用我的Nito.AsyncEx.Tasks库中的WaitAsync方法:
Task task = restService.GetRequestAsync(articleAdr, articleParams);
await task.WaitAsync(cts.Token);
var result = await task;
如果
CancellationToken
是用户请求的取消,并且
Task.Delay
是您想要应用的超时时间,那么我建议将超时建模为另一种取消方式:
Task task = restService.GetRequestAsync(articleAdr, articleParams);
using (var timeoutCts = CancellationTokenSource.CreateLinkedTokenSource(cts.Token))
{
timeoutCts.CancelAfter(1000);
await task.WaitAsync(timeoutCts.Token);
}
var result = await task;
如果你不想使用
Nito.AsyncEx.Tasks
,那么你最好的选择可能是像这样(假设
Task.Delay
用作超时控制而
CancellationToken
是用户取消请求):
Task task = restService.GetRequestAsync(articleAdr, articleParams);
var completed = await Task.WhenAny(task, Task.Delay(1000, cts.Token));
if (completed != task)
throw new OperationCanceledException();
var result = await task;