频道栏目
读书频道 > 软件开发 > C# > C#并发编程经典实例
2.1 暂停一段时间
2014-12-06 13:35:38     我来说两句
收藏   我要投稿

本文所属图书 > C#并发编程经典实例

本书全面讲解C 并发编程技术,侧重于 NET 平台上较新、较实用的方法。全书分为几大部分:首先介绍几种并发编程技术,包括异步编程、并行编程、TPL 数据流、响应式编程;然后阐述一些重要的知识点,包括测试技  立即去当当网订购

问题

需要让程序(以异步方式)等待一段时间。这在进行单元测试或者实现重试延迟时非常有用。本解决方案也能用于实现简单的超时。

解决方案

Task 类有一个返回Task 对象的静态函数Delay,这个Task 对象会在指定的时间后完成。

如果程序使用Microsoft.Bcl.Async 这个NuGet 库,则Delay 是TaskEx 类的成员,而不是Task 类的成员。

下面的例子用于单元测试,定义了一个异步完成的任务。在模拟一个异步操作时,至少要测试“同步成功”“异步成功”和“异步失败”这三种情况,这一点很重要。下面的例子返回一个Task 对象,用于“异步成功”测试。

static async Task<T> DelayResult<T>(T result, TimeSpan delay)
{
await Task.Delay(delay);
return result;
}

下一个例子实现了一个简单的指数退避。指数退避是一种重试策略,重试的延迟时间会逐次增加。在访问Web 服务时,最好的方式就是采用指数退避,它可以防止服务器被太多的重试阻塞。

在实际产品的开发中,建议你采用更周密的方案,例如微软企业库中的瞬间错误处理模块(Transient Error Handling Block)。下面的代码只是一个使用Task.Delay 的简单例子。

static async Task<string> DownloadStringWithRetries(string uri)
{
using (var client = new HttpClient())
{
// 第1 次重试前等1 秒,第2 次等2 秒,第3 次等4 秒。
var nextDelay = TimeSpan.FromSeconds(1);
for (int i = 0; i != 3; ++i)
{
try
{
return await client.GetStringAsync(uri);
}
catch
{
}
await Task.Delay(nextDelay);
nextDelay = nextDelay + nextDelay;
}
// 最后重试一次,以便让调用者知道出错信息。
return await client.GetStringAsync(uri);
}
}

最后的例子用Task.Delay 实现一个简单的超时功能。本例中代码的目的是:如果服务在3秒内没有响应,就返回null。

static async Task<string> DownloadStringWithTimeout(string uri)
{
using (var client = new HttpClient())
{
var downloadTask = client.GetStringAsync(uri);
var timeoutTask = Task.Delay(3000);
var completedTask = await Task.WhenAny(downloadTask, timeoutTask);
if (completedTask == timeoutTask)
return null;
return await downloadTask;
}
}

讨论

Task.Delay 适合用于对异步代码进行单元测试或者实现重试逻辑。要实现超时功能的话,最好使用CancellationToken。

参阅

2.5 节介绍如何用Task.WhenAny 来判断哪个任务是首先完成的。

9.3 节介绍用CancellationToken 实现超时功能的方法。
您对本文章有什么意见或着疑问吗?请到论坛讨论您的关注和建议是我们前行的参考和动力  
上一篇:概述
下一篇:2.2 返回完成的任务
相关文章
图文推荐
排行
热门
最新书评
特别推荐

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训 | 举报中心

版权所有: 红黑联盟--致力于做实用的IT技术学习网站