异步编程基础——暂停一段时间
问题
程序需要异步等待一段时间。在进行单元测试或实现重试延时时,这是一种常见场景
解决方案
在Task类型中有个Delay静态方法,该方法在指定时间结束后返回已完成的任务
async Task<T> DelayResult<T>(T result,TimeSpan delay)
{
await Task.Delay(delay);
return result;
}
对于生产代码,推荐使用更为彻底的解决方案,比如Polly NuGet库
Task.Delay还可用作简单的超时,通常会使用CancellationTokenSource这种类型来实现超时,当然也可以用无限任务(Task.Delay)来包装取消令牌,从而提供在指定时间之后取消的任务,然后,把那个计时任务配合Task.WhenAny一起使用,实现软超时
async Task<String> DownloadStringWithTimeout(HttpClient client,string uri)
{
using var cts=new CancellationTokenSource(TimeSpan.FromSecond(3));
Task<String> downloadTask=client.GetStringAsync(uri);
Task timeoutTask=Task.Delay(Timout.InfiniteTimeSpan,cts,Token);
Task completedTask=await Task.WhenAny(downloadTask,timeoutTask);
if(completedTask==timeoutTask)
{
return null;
}
return await downloadTask;
}
讨论
对异步代码的单元测试或重试逻辑的实现来说,Task.Delay是很好的选择。然而,如果要实现超时,CancellationToken通常是更好的选择。