码迷,mamicode.com
首页 > 其他好文 > 详细

13.1.1 异步工作流为什么重要?

时间:2015-02-08 11:35:44      阅读:218      评论:0      收藏:0      [点我收藏+]

标签:异步工作流   f#   函数编程   实用函数编程   

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 = newStreamReader(stream);

  reader.BeginReadToEnd(asyncRes2=> {    <-- 不退出

    var html =reader.EndReadToEnd(asyncRes2);

    Console.WriteLine(html);

  });

});

 

要写这种代码,是很难的。虽然我们使用了 C# 3.0 的 lambda 函数,代码看起来仍然很复杂。我们必须改变其结构;不能顺序地写代码,而是用嵌套的回调的序列。

前面的代码段还有另外一个问题,在 .NET 框架中并没有BeginReadToEnd 方法,因此,我们可能必须自己实现异步下载。不幸的是,不可能使用简单的顺序代码实现,因为我们需要以缓冲的方式下载页面。如果以异步风格写这段代码(使用嵌套的回调),我们不可能使用任何内置的结构,例如,while 循环。

我们将会看到,异步工作流能解决所有在写下载程序时遇到的问题,能够以通常的顺序方式写代码,使用标准的控制结构,比如递归,或者甚至是 while 循环。代码异步执行,因此,工作流等待操作完成,而不需要使用专门的线程。在下一节,我们将学习如何使用 F# 异步工作流,来实现我们刚讨论的示例。

 

13.1.1 异步工作流为什么重要?

标签:异步工作流   f#   函数编程   实用函数编程   

原文地址:http://blog.csdn.net/hadstj/article/details/43635665

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!