`
tianshibaijia
  • 浏览: 1125091 次
文章分类
社区版块
存档分类
最新评论

13.1.3 理解工作流的工作方式

 
阅读更多
13.1.3 理解工作流的工作方式



在前一章中,我们看到,用计算表达式写的 F# 代码被转换成一个表达式,它使用由适当计算生成器提供的基元。对于异步工作流,这意味着,let! 结构被转换成对 async.Bind 的调用,return 被转换成 async.Return。此外,异步工作流是延迟的。这意味着,计算本身要打包到一个额外的基元,确保整个代码括在一个函数中。这个函数在后面工作流启动时执行。清单 13.3 显示从清单 13.2 工作流的转换后的版本。



Listing 13.3 Asynchronous workflow constructed explicitly (F#)



async.Delay(fun () –>
let request = HttpWebRequest.Create(url)
async.Bind(request.AsyncGetResponse(), fun response –>
async.Using(response, fun response –>
let stream = response.GetResponseStream()
async.Using(new StreamReader(stream), fun reader –>
reader.AsyncReadToEnd() )
)
)
)



Delay 成员把一个函数打包到一个工作流值,可以在以后执行。Lambda 函数体作为一全参数值,创建一个 HTTP 请求,使用自定义的异步值绑定,把一个值赋给 resp 符号。编译器把每个使用的绑定转换成对 Using 成员的调用,这是另一种基元,可以通过计算表达式生成器可选地提供的。它负责在工作流结束时,释放对象,不管成功,还是有错误。

Delay 成员是计算生成器成员之一,当实现计算表达式时,我们可以提供。在清单 13.3 中,它取一个返回异步工作流 (类型是 unit ->Async<’a>)的函数,并返回工作流值(Async<’a>),它打包了这个函数。由于有了这个基元,整个计算被括在一个函数之内,它并不在我们创建 Async<’a> 值时执行。这是与前一章的例子的一个重要区别,比如,option<'a> 类型。一个选项表示一个值,所以,计算表达式立即运行,执行这个计算,并返回一个新的选项值,只是工作流表示计算。当我们详细地看过 Async<’a> 类型之后,其意思主就会变得更清晰。

出现在清单 13.3 中的其他基元类型是 Bind 成员。就像我们在前一章中学习的,这对于所有的计算表达式是很重要的。在异步工作流中,Bind 可以启动一个操作,而不会阻塞调用者线程。下面的列表概述了当我们使用基元,比如:Async.RunSynchronously,执行工作流时发生的步骤:

1、作为参数值给 Delay 基元的函数启动执行。它同步创建一个对象,表示对给定的 URL 的 HTTP 请求。

2、调用 AsyncGetResponse。结果是一个基元的异步工作流,知道如何启动请求,当操作完成时调用指定的函数。

3、我们执行这个 Bind 成员,并把在第二步中的工作流作为第一个参数值给它,再给它一个函数,这个函数取 HTTP 响应作为一个参数值,它应该在工作流完成时执行。这个函数被称为连续(continuation),这是我们已经看到过的一个术语。(我们在第 10 章讨论递归时,使用过,是作为一个累加器参数,为了累加希望在以后运行的更多代码的。)

4、这个 Bind 成员运行由 AsyncGetResponse 创建的工作流,向它传递指定的连续。基元工作流然后调用 .NET 的 BeginGetResponse 方法,指示系统启动下载响应,当操作完成时调用给定连续。在这点,Bind 成员返回,正在执行操作的线程被释放,继续做其它工作,或者它被返回给线程池。

5、当响应准备就绪时,系统将调用这个连续。工作流使用 EndGetResponse 的 .NET 方法获取响应对象,执行给 Bind 成员的,表示工作流的其余部分。注意,系统再从线程池取一个线程,所以,每次我们使用 let! 基元时,工作流的其余部分可能在不同的线程上执行。

关键的一点是,当我们执行异步工作流时,不要等待结果。相反,我们把连续给它作为参数值;当工作流中的相应步骤完成时,这个连续就执行。有关异步工作流的主要事情是,我们不必显式写使用连续的代码。编译器把 let! 基元转换成对 Bind 成员的调用,自动创建连续。



研究异步工作流的类型



我们可以使用异步工作流,而不必了解所有的详细信息,但是,你对它们如何实现可能有点兴趣。我们已经看到,异步工作流类似于函数,因为,它们表示的计算可以在以后执行。在 F# 库中,类型用函数表示。类型有点复杂,但是,最简单的异步计算可以使用下面的代码来表示:



type Async<'T> = (('T -> unit) * (exn -> unit) * (unit -> unit)) –> unit



这是一个函数,它取三个参数值,作为一个元组,并返回一个 unit 值。这三个参数值是重要的,因为它们是连续-函数,可以在异步工作流完成时调用。第一个被称为成功连续,其类型是 'T -> unit,这就意味着,它取这个工作流的结果。当这个工作流完成时,连续将调用。然后,它可以运行另一个工作流,或者任何其他代码。第二个是异常的连续,它取 exn 值作为参数值,这是 F# .NET Exception 类型的缩写。如你所猜想的,它使用在工作流执行的操作失败时。第三个函数称为取消连续,工作流被取消时可以当触发。



虽然异步工作流的精确实现细节并不是必要的,能够创建自己的基元工作流,它很有用,相当于清单 13.3 中的使用 AsyncGetResponse 方法。然后,可以使用构造块的其余部分,用最小的烦恼来异步运行自己的代码。


分享到:
评论

相关推荐

    .Net.Framework3.5开发技术详解

    .Net.Framework3.5开发技术详解 完整程度:99%完整 少最后8页 清晰度:一般 格式:PDF 总页数:402 内容简介 《.NET Framework3.5开发技术详解》全面讲解了.NET Framework 3.5开发中各方面的技术...19.6 工作流的XAML表示

    Spring攻略(第二版 中文高清版).part2

    13.1.3 工作原理 504 13.2 创建单元测试和集成测试 509 13.2.1 问题 509 13.2.2 解决方案 509 13.2.3 工作原理 510 13.3 Spring MVC控制器的单元测试 518 13.3.1 问题 518 13.3.2 解决方案 518 ...

    Spring攻略(第二版 中文高清版).part1

    13.1.3 工作原理 504 13.2 创建单元测试和集成测试 509 13.2.1 问题 509 13.2.2 解决方案 509 13.2.3 工作原理 510 13.3 Spring MVC控制器的单元测试 518 13.3.1 问题 518 13.3.2 解决方案 518 ...

    .Net.Framework3.5开发技术详解[中文][PDF][VOL1]

    作为初学入门选择方向的好教材 许多技术人员在面对.NET Framework 3.0/3.5大量的新知识、新技术的时候感到彷徨,对自己现有的技术知识是否过时会产生疑问,对新技术会产生抵触的情绪,...19.6 工作流的XAML表示 407

    .Net.Framework3.5开发技术详解[中文][共二卷][PDF][VOL2]

    作为初学入门选择方向的好教材 许多技术人员在面对.NET Framework 3.0/3.5大量的新知识、新技术的时候感到彷徨,对自己现有的技术知识是否过时会产生疑问,对新技术会产生抵触的情绪,...19.6 工作流的XAML表示 407

    PROJECT 2007宝典 9/9

     12.2 理解计算方式选项  12.3 更新任务反映实际信息   12.3.1 设置实际的开始和完成日期   12.3.2 记录实际工期   12.3.3 设置完成百分比值   12.3.4 设置完成的工时   12.3.5 设置剩余工期  ...

    PROJECT 2007宝典 7/9

     12.2 理解计算方式选项  12.3 更新任务反映实际信息   12.3.1 设置实际的开始和完成日期   12.3.2 记录实际工期   12.3.3 设置完成百分比值   12.3.4 设置完成的工时   12.3.5 设置剩余工期  ...

    PROJECT 2007宝典 1/10

     12.2 理解计算方式选项  12.3 更新任务反映实际信息   12.3.1 设置实际的开始和完成日期   12.3.2 记录实际工期   12.3.3 设置完成百分比值   12.3.4 设置完成的工时   12.3.5 设置剩余工期  ...

    PROJECT 2007宝典 8/9

     12.2 理解计算方式选项  12.3 更新任务反映实际信息   12.3.1 设置实际的开始和完成日期   12.3.2 记录实际工期   12.3.3 设置完成百分比值   12.3.4 设置完成的工时   12.3.5 设置剩余工期  ...

    PROJECT 2007宝典 5/9

     12.2 理解计算方式选项  12.3 更新任务反映实际信息   12.3.1 设置实际的开始和完成日期   12.3.2 记录实际工期   12.3.3 设置完成百分比值   12.3.4 设置完成的工时   12.3.5 设置剩余工期  ...

    PROJECT 2007宝典 6/9

     12.2 理解计算方式选项  12.3 更新任务反映实际信息   12.3.1 设置实际的开始和完成日期   12.3.2 记录实际工期   12.3.3 设置完成百分比值   12.3.4 设置完成的工时   12.3.5 设置剩余工期  ...

    PROJECT 2007宝典 3/9

     12.2 理解计算方式选项  12.3 更新任务反映实际信息   12.3.1 设置实际的开始和完成日期   12.3.2 记录实际工期   12.3.3 设置完成百分比值   12.3.4 设置完成的工时   12.3.5 设置剩余工期  ...

    PROJECT 2007宝典 2/9

     12.2 理解计算方式选项  12.3 更新任务反映实际信息   12.3.1 设置实际的开始和完成日期   12.3.2 记录实际工期   12.3.3 设置完成百分比值   12.3.4 设置完成的工时   12.3.5 设置剩余工期  ...

    PROJECT 2007宝典 4/9

     12.2 理解计算方式选项  12.3 更新任务反映实际信息   12.3.1 设置实际的开始和完成日期   12.3.2 记录实际工期   12.3.3 设置完成百分比值   12.3.4 设置完成的工时   12.3.5 设置剩余工期  ...

    Visual.Basic.2010.&.NET4.高级编程(第6版)-文字版.pdf

    5.3.2 使用xaml声明工作流 264 5.4 小结 265 第6章 异常处理和调试 267 6.1 visual studio 2010 team system的新增内容:历史调试 267 6.2 与visual basic 6兼容的注意事项 268 6.3 .net中的异常处理 268 ...

    精通CSS+DIV网页样式与布局视频教材

    第10章 理解CSS定位与div布局 10.1 div标记与span标记 10.1.1 概述 10.1.2 div与span的区别 10.2 盒子模型 10.2.1 盒子模型的概念 10.2.2 border 10.2.3 padding 10.2.4 margin 10.3 ...

    WPF编程宝典 part1

    13.1.3 使用CombinedGeometry融合 几何图形 311 13.1.4 使用PathGeometry绘制曲线和 直线 313 13.1.5 微语言几何图形 318 13.1.6 使用几何图形进行剪裁 319 13.2 图画 320 13.2.1 显示图画 322 13.2.2 导出插图 324 ...

    WPF编程宝典 part2

    13.1.3 使用CombinedGeometry融合 几何图形 311 13.1.4 使用PathGeometry绘制曲线和 直线 313 13.1.5 微语言几何图形 318 13.1.6 使用几何图形进行剪裁 319 13.2 图画 320 13.2.1 显示图画 322 13.2.2 导出插图 324 ...

    精通ANDROID 3(中文版)1/2

    13.1.3 服务在主线程上运行  13.1.4 ContentProvider在主线程上运行  13.1.5 单一主线程的影响  13.1.6 线程池、ContentProvider、外部服务组件  13.1.7 线程实用程序:发现线程  13.2 处理程序  13.2.1...

    精通Android 3 (中文版)2/2

    13.1.3 服务在主线程上运行  13.1.4 ContentProvider在主线程上运行  13.1.5 单一主线程的影响  13.1.6 线程池、ContentProvider、外部服务组件  13.1.7 线程实用程序:发现线程  13.2 处理程序  13.2.1...

Global site tag (gtag.js) - Google Analytics