13.1.1 异步工作流为什么重要?
来源:互联网 发布:体现中国实力的数据 编辑:程序博客网 时间:2024/06/05 11:06
13.1.1 异步工作流为什么重要?
假设我们要下载网页的内容,在应用程序中使用,我们可以使用 System.Net 命名空间下的 WebClient 类,但是不能演示需要解决的运行复杂、长时间操作的问题。因此,我们需要显式创建 HTTP 请求,然后,下载数据:
var req = HttpWebRequest.Create("http://manning.com");var resp = req.GetResponse(); <-- 初始化连接var stream = resp.GetResponseStream();var reader = new StreamReader(stream); <-- 下载网页var html = reader.ReadToEnd();Console.WriteLine(html);
这段代码能运行,但远不完美。有两个地方执行 HTTP 通讯,一是初始化与服务器的 HTTP 连接;二是下载网页。这两个操作都可能会花很长时间,也都可能会阻塞活动的线程,从而导致应用程序没有响应。
要解决这个问题,可以把下载放在单独的线程中。但是,使用线程的代价昂贵,因此,这种方法会限制能够并行下载的数量;此外,大部分时间这个线程处于等待响应,造成线程资源的浪费。要完美地解决问题,应使用异步编程接口,它能在操作完成时,执行回调,触发请求:
var req = HttpWebRequest.Create("http://manning.com");req.BeginGetResponse(asyncRes1 => { <-- 开始操作 var resp = req.EndGetResponse(asyncRes1); var stream = resp.GetResponseStream(); var reader = new StreamReader(stream); reader.BeginReadToEnd(asyncRes2 => { <-- 不退出 var html = reader.EndReadToEnd(asyncRes2); Console.WriteLine(html); });});
写这种代码是有难度的,尽管我们使用了 C# 3.0 中的 lambda 函数,代码看起来仍然很复杂。我们必须改变代码的结构,用嵌套的回调的序列代替代码序列。
前面的代码段还有另外一个问题,在 .NET 框架中并没有 BeginReadToEnd 方法,因此,还必须自己实现异步下载。不幸的是,不可能使用简单的代码序列来实现,因为我们需要以缓冲的方式下载页面。如果我们用异步方式写这段代码(使用嵌套的回调),就不能使用任何的内置结构,例如,while 循环。
我们将会看到,异步工作流能够解决下载时遇到的所有问题。代码可以用通常的顺序方式,标准的控制结构,比如递归,或者甚至是 while 循环。代码就能异步执行,工作流等待操作完成,而不需要使用专门的线程。在下一节,我们将学习如何使用 F# 异步工作流,来实现刚才讨论的示例。
- 13.1.1 异步工作流为什么重要?
- 13.1.1 异步工作流为什么重要?
- 13.1.1 异步工作流为什么重要?
- 13.1 异步工作流
- 13.1 异步工作流
- 13.1 异步工作流
- 工作流重要站点收集
- 工作流,task,异步
- 工作流框架的重要名词!
- 我们为什么选择工作流
- 我们为什么选择工作流?
- 为什么选择工作流
- 为什么我们需要工作流
- 观念为什么重要?
- 流程为什么重要?
- 【绪论】算法为什么重要?
- 为什么算法如此重要
- 为什么size_t重要?
- 在Windows下,python-Levenshtein的安装
- GitHub的使用
- PAT1006-Sign In and Sign Out
- 关于编译的一些事儿:从头开始整理一套编译框架(一)
- Java 获取文件的基本信息
- 13.1.1 异步工作流为什么重要?
- Unreal里的SetLifeSpan()和InitialLifeSpan
- RESTful最佳实践——三、REST快速提示
- CA自认证和双向认证证书生成方法以及Nginx配置
- 13.1.2 异步下载网页
- linux下安装mysql5.7.17及简单配置
- 被工作逼到学习Windows编程的地步
- AngularJS实现轮播图
- 小博老师解析Java核心技术 ——JDBC普通查询操作