
异步编程
文章平均质量分 58
心想才事成
这个作者很懒,什么都没留下…
展开
-
13.1.1 异步工作流为什么重要?
13.1.1 异步工作流为什么重要? 假设我们要下载 web 页的内容,以便可以在我们的应用程序中使用。我们可以使用来自 System.Net 命名空间下的 WebClient 类,但是,不会演示当我们需要的问题,当我们运行复杂、长时间运行的操作时。相反,我们将首先显式创建 HTTP 请求,然后,下载数据:var req = HttpWebRequest.Create翻译 2011-11-20 16:53:27 · 1075 阅读 · 0 评论 -
大文件的处理
大文件的处理let rec transforAsync (streamIn:Stream) (streamOut:Stream) buffer = async{ let! lengthRead = streamIn.AsyncRead(buffer, 0, buffer.Length) if (lengthRead >0) then do! streamOut.Asy原创 2013-02-25 10:31:54 · 890 阅读 · 0 评论 -
异步编程(Asynchronous Programming)
异步编程(Asynchronous Programming) 异步编程与我们所看过的其他并行编程形式有一些不同,讨论的其他主题可以有大量的线程并行运行,可以完全利用系统中可用的处理器;而在异步编程中,需要避免阻塞线程,我们在这一章的第一节“线程、内存、锁定和阻塞”中已经对阻塞线程的概念有所了解了。阻塞的线程是不能工作的线程,因为它需要等待其他任务的完成;线程等待的通常任务是操作系统执行的输翻译 2014-05-15 10:26:54 · 4004 阅读 · 0 评论 -
异步使用 HTTP
异步使用 HTTP 到现在,我们所关注的还只是通过 HTTP 一次检索一个文档,或进行一次更新,在这种情况下,使用异步编程模式就没什么意义了。然而,我们通常的想法是一次能进行多个 HTTP 请求,这样,就可以从多个源检索、汇总数据,在这种情况下,使用 F# 的异步工作流,我们第一次碰到是在第十章“异步编程”一节,就能极大提高应用程序的性能。事实上,我们可能还希望能得到比使用本地磁盘更高的性翻译 2014-05-22 17:28:22 · 2526 阅读 · 0 评论 -
13.2 连接到世界银行
13.2 连接到世界银行我们把异步工作流的内容放在有关探索式编程(explorative programming)这一章来讨论,绝不是偶然的,我们每天要处理的很多重要数据源,都是以网站服务,或者其他基于网站应用程序的形式,在线提供。我们已经知道,对于获取数据,异步工作流是 F# 的基本功能。 高效下载数据并不是唯一的问题。数据源返回的数据,通常是非类型化的格式(比如,纯文本,或者没有正式定义架构的翻译 2017-01-13 22:17:21 · 232 阅读 · 0 评论 -
13.2.1 访问世界银行的数据
13.2.1 访问世界银行的数据在本章使用的数据源,是由世界银行提供的服务。世界银行是为发展中国家提供资金和知识的国际组织识别哪种类型的支援最有效,确定需求在哪里,评估对发展中国家的经济,生活质量,环境是否产生了影响,是其工作的一部分。世界银行有一组数据,称为世界发展指标(World Development Indicators),包含了许多国家的信息,而且数据可在线使用。在本章,我们将使用有关环境翻译 2017-01-13 22:19:09 · 695 阅读 · 0 评论 -
13.2.2 从故障中恢复
13.2.2 从故障中恢复世界银行服务对每个用户密钥每天请求数量有限制,还限制了请求的频率,因此,如果我们一次运行大量的请求,有可能会出错。解决的方法是捕获异常,稍后重试请求。 清单 13.7 实现的循环,重复执行请求,直到成功,或者尝试 20 次为止。使用异常报告失败,使用 F# 的 try … with 结构捕捉异常。清单 13.7 重复运行 web 请求 (交互式 F#)> let worl翻译 2017-01-13 22:20:49 · 302 阅读 · 0 评论 -
13.1 异步工作流
13.1 异步工作流有许多地方需要异步操作,比如,磁盘操作、调用 web 服务,或者连接数据库,异步工作流能够显著提高性能。应用程序执行异步操作时,很难预测操作什么时候完成。如果不能正确处理异步操作,应用程序的效率反而会低下,甚至可能停止响应。 异步操作代码首先不能阻止调用线程,避免出现问题,而使用当前的技术很难实现。但是,有了 F#,就极大地简化了,因为它有异步工作流(asynchronous翻译 2017-01-11 20:44:10 · 318 阅读 · 0 评论 -
13.1.1 异步工作流为什么重要?
13.1.1 异步工作流为什么重要?假设我们要下载网页的内容,在应用程序中使用,我们可以使用 System.Net 命名空间下的 WebClient 类,但是不能演示需要解决的运行复杂、长时间操作的问题。因此,我们需要显式创建 HTTP 请求,然后,下载数据:var req = HttpWebRequest.Create("http://manning.com");var resp = req.G翻译 2017-01-11 20:46:34 · 379 阅读 · 0 评论 -
13.1.2 异步下载网页
13.1.2 异步下载网页 使用异步工作流抓取网页内容,需要引用 FSharp.PowerPack.dll库,它提供了许多 .NET方法的异步版本。开发独立的应用程序时,可以使用添加引用命令;在这一章,我们将使用交互式开发模式,因此,创建新的 F#脚本文件,使用 #r指令(清单 13.1)。 清单13.1使用异步工作流写代码(交互式F#) > #r "翻译 2017-01-11 20:49:00 · 321 阅读 · 0 评论 -
13.3 浏览并获取数据
13.3 浏览并获取数据通过前面几个例子,我们已经知道,世界银行数据服务返回的数据是 XML 文档,因此,不管如何处理数据,首先要将它转换为 F# 类型。在第七章,我们在XML 和自定义的差别联合类型之间进行过转换,在这里,将使用元组和序列。这种数据结构非常简单,交互式处理数据时,需要频繁地修改代码,既要调整如何使用现有的值,还要下载不同的信息,对于这种任务来说,元组更适合,不会频繁地重命名值。翻译 2017-01-16 20:12:39 · 267 阅读 · 0 评论 -
13.3.3 获取指标
13.3.3 获取指标获取有关国家或地区的数据,需要使用世界银行服务的不同函数,函数的路径是 /countries/indicators,可以在 Data Calls 选项卡的 Query Generator(查询生成器)中找到,它能够请求指定国家在特定时间段的有关指标数据。我们不必单独下载每个感兴趣的地区数据,可以一次性地获得所有国家的信息,在内存中进行处理。以这种方式可以下载更多的数据,而请求的翻译 2017-01-16 20:18:58 · 295 阅读 · 0 评论 -
13.1.4 创建工作流基本操作
bvio13.1.3 理解工作流的原理从前一章我们知道,用计算表达式写的 F# 代码,会由对应的计算生成器,转换成使用基本操作的表达式。对于异步工作流来说,let! 结构转换成对 async.Bind 的调用,return 转换成 async.Return;此外,异步工作流自动延迟,因此,计算本身需要包装成另外的基本操作,以确保整个代码包含在一个函数中,这个函数能够在后面工作流启动时执行。清单 13翻译 2017-01-12 20:45:47 · 381 阅读 · 0 评论 -
13.1.3 理解工作流的原理
13.1.3 理解工作流的原理从前一章我们知道,用计算表达式写的 F# 代码,会由对应的计算生成器,转换成使用基本操作的表达式。对于异步工作流来说,let! 结构转换成对 async.Bind 的调用,return 转换成 async.Return;此外,异步工作流自动延迟,因此,计算本身需要包装成另外的基本操作,以确保整个代码包含在一个函数中,这个函数能够在后面工作流启动时执行。清单 13.3 是翻译 2017-01-12 20:44:37 · 569 阅读 · 0 评论 -
13.3.2 提取地区代码
13.3.2 提取地区代码我们下载函数的输出结果是字符串,因此,需要将字符串解析为 XML 文档。由于这个操作经常要用,所以,我们要写一个简单的包装函数,用 worldBankDownload 下载数据,把返回结果转换成 XDocument 对象。下载操作异步运行,因此,我们使用异步工作流实现这个函数:let worldBankRequest(props) = async { let! text翻译 2017-01-16 20:17:08 · 388 阅读 · 0 评论 -
13.4 从数据中收集信息
13.4 从数据中收集信息从互联网下载大量的数据很容易,但从中收集到有用的信息就困难了。本章到目前为止,我们已经下载了地区列表,并把它转换为地区名字的序列;然后,下载一组包含所有地区和国家信息的 XML 文档。在本节,我们将把这些非类型化的 XML 数据转换为类型化的数据结构,这样,信息可以方便地显示给用户。翻译 2017-01-17 20:14:18 · 248 阅读 · 0 评论 -
13.4.1 读取值
13.4.1 读取值我们首先要做的是从 XML 中读取感兴趣的数据。定义一个函数,参数为 XDocument 对象的列表(对应于数据集的每个页面),返回序列类型,每个元素包含了指标、 地区名,以及观测的年份。 清单 13.14 展示了 readValues 函数,以及辅助函数,从表示一条记录的 XML 节点中读数据,两个函数有一个名为 parse 的参数,是真正解析字符串值的函数,我们很快就会知道翻译 2017-01-17 20:15:59 · 410 阅读 · 0 评论 -
13.4.2 用计量单位格式化数据
13.4.2 用计量单位格式化数据XML 数据中的许多指标,都只能转换为浮点数(float);这当然是对的,因为面积和森林覆盖率都是数字,但是,这种数据没有更多的意义。把从非类型化的 XML 数据转换成 F# 类型化数据结构,其目的是通过类型注解,更好地了解这些值含义。为了使类型更具体,我们可以使用计量单位(units of measure),这在第二章提到过。使用这个功能,面积按平方公里计,森林覆翻译 2017-01-17 20:19:02 · 427 阅读 · 0 评论 -
Async vs sync benchmark
文章来自:http://fssnip.net/cQAsync vs sync benchmarkQuick benchmark to compare the throughput performance of F# MailboxProcessor using asynchronous workflows and a synchronous agent using a lock and转载 2012-06-27 21:31:05 · 795 阅读 · 0 评论 -
16.5.2 并发访问邮箱
16.5.2 并发访问邮箱 邮箱处理器每次(很少)只处理一个邮件,但它可以安全地从多个线程访问。用于发布消息给处理器的所有方法(例如,Post 和 PostAndReply)都是线程安全的。让我们创建一个小应用程序,演示从三个线程并发访问我们的邮箱处理器。 清单 16.20 表示的情况是,有两个线程在重复地执行计算,然后,发送状态更新给邮箱处理器。为了使代码简单,我们的线翻译 2012-01-19 15:08:55 · 994 阅读 · 0 评论 -
13.1 异步工作流
13.1 异步工作流 有许多地方需要使用异步操作。当我们使用磁盘、调用 web 服务,或者连接到数据库时,异步工作流可能有显著的性能优势。当应用程序执行异步操作时,很难预测什么时修操作将完成。如果不能正确处理异步操作,应用程序就会效率低下,甚至可能停止响应。 写出能够执行异步操作,而不会阻止调用线程的代码,避免出现问题是必要的,但是,使用当前的技术很难实现。在 F# 中翻译 2011-11-20 14:42:57 · 531 阅读 · 0 评论 -
13.1.2 异步下载网页
13.1.2 异步下载网页 在我们使用异步工作流来获取网页内容之前,需要引用 FSharp.PowerPack.dll 库,它包含许多 .NET 方法的异步版本。当开发独立的应用程序时,可以使用添加引用命令。在这一章中,我们将使用互动开发模式,创建一个新的 F# 脚本文件,使用 #r 指令(清单 13.1)。 Listing 13.1 Writing code using翻译 2011-11-21 11:26:47 · 767 阅读 · 0 评论 -
13.2.1 访问世界银行的数据
13.2.1 访问世界银行的数据 我们在本章中使用的数据源,是由世界银行提供的服务,它是为发展中国家提供资金和知识的国际组织。作为其工作的一部分,该组织需要确定对评估发展中国家,哪种类型的支持最有效,确定需求在哪里,以及对经济、生活质量、环境是否产生了影响。世界银行有一组数据,称为世界发展指标(World Development Indicators),它包含了许多国家的信息,而且翻译 2011-11-22 15:07:42 · 1040 阅读 · 0 评论 -
13.1.4 创建基元工作流
13.1.4 创建基元工作流 F# PowerPack 库包含许多重要的 I/O 操作异步版本,但是,它可不能包括所有。为此,F# 库还提供了构建自己的基元工作流的方法。如果要运行在工作流内部的操作,使用的标准 .NET 模式,并提供了 BeginOperation 和 EndOperation 方法,可以使用 Async.FromBeginEnd 方法。如果你把这两种方法给翻译 2011-11-21 19:41:35 · 719 阅读 · 0 评论 -
13.2 连接到世界银行
13.2 连接到世界银行 我们在一章讨论有关探索式编程(explorative programming),放在异步工作流上,这决不是偶然的。我们今天要处理的很多有趣的数据源,都是以 web 服务的形式,或者是其他基于 web 的应用程序,在线可用。如我们所见,异步工作流是 F# 获取数据的本质特征。 高效地下载数据并不是我们唯一的问题。数据源返回的数据通常是非类型化的格式翻译 2011-11-22 11:15:27 · 587 阅读 · 0 评论 -
13.2.2 从故障中恢复
13.2.2 从故障中恢复 世界银行服务对每个用户密钥每一天请求数量有限制,也限制了请求的频率。这意味着,如果我们一次运行大量的请求,有些可能会返回错误。解决方法是捕获异常,稍后重试请求。 清单 13.7 实现一个循环,重复执行的请求,直到成功,或者尝试 20 次。使用异常报告失败, 使用 F# 的 try … with 结构捕捉异常。Listi翻译 2011-11-22 19:13:00 · 746 阅读 · 0 评论 -
13.3 探索并获取数据
13.3 探索并获取数据 就像我们在最后的几个例子中所看到的,世界银行数据服务返回数据是 XML 文档,这样,我们可以写任何代码,以有意义的方式处理数据之前,需要将它转换为 F# 类型。在第 7 章,我们在XML 和我们自己自定义的差别联合类型之间进行过转换,但在这里,我们要使用的是元组和序列。这是因为,这样的数据结构很简单,当我们交互式处理数据时,需要频繁地修改代码,既要调整翻译 2011-11-23 09:10:00 · 645 阅读 · 0 评论 -
13.3.1 实现 XML 辅助函数
13.3.1 实现 XML 辅助函数 LINQ to XML 主要用于 C# 和 VB,在 F# 中使用可能有些麻烦。例如,F# 不支持隐式类型转换(因为这会使类型推断复杂),所以,每次我们指定元素名,必须使用 XName.Get,而不是只使用一个字符串。或者,我们可以写一个简单的工具函数或自定义运算符,来完成这些。 我们可以很容易地实现几个 F# 函数,把 LINQ t翻译 2011-11-23 15:03:17 · 650 阅读 · 0 评论 -
13.3.2 提取区域的代码
13.3.2 提取区域的代码 我们下载函数的结果是一个字符串,所以,需要将字符串作解析为 XML 文档。我们将频繁需要这个操作,所以,要写一个简单的打包函数,使用 worldBankDownload 下载数据,返回结果为 XDocument 对象。下载执行异步,因此,要使用异步工作流实现这个函数:let worldBankRequest(props) = as翻译 2011-11-23 22:29:27 · 682 阅读 · 0 评论 -
13.3.3 获取各项指标
13.3.3 获取各项指标 若要获取有关国家或地区的数据,需要使用世界银行服务的不同函数。函数的路径是 /countries/indicators(/国家/指标),可以在 Data Calls 选项卡下的 Query Generator(查询生成器)中找到。能够请求指定国家特定时间段内的有关指标数据。不是单独下载我们感兴趣的数据每个区域,而是一次获取所有国家的信息,并在内存中翻译 2011-11-24 19:30:14 · 737 阅读 · 0 评论 -
13.1.3 理解工作流的工作方式
13.1.3 理解工作流的工作方式 在前一章中,我们看到,用计算表达式写的 F# 代码被转换成一个表达式,它使用由适当计算生成器提供的基元。对于异步工作流,这意味着,let! 结构被转换成对 async.Bind 的调用,return 被转换成 async.Return。此外,异步工作流是延迟的。这意味着,计算本身要打包到一个额外的基元,确保整个代码括在一个函数中。这个函数在翻译 2011-11-21 18:48:56 · 964 阅读 · 0 评论 -
16.5.1 创建一个状态机处理器
16.5.1 创建一个状态机处理器 我们前面创建的邮箱处理器是相当简单的,它能处理四种不同的消息,它保持一些本地状态,但它始终能够立即处理收到任何消息。情况不可能始终是这样的。如果一个邮箱处理器将一条消息发送到其他两个处理器,它可能需要在响应任何其他消息之前,收集这些处理器的回复。 我们可以写出表示状态机邮箱处理器,以类似于用异步工作流绘制矩形事件处理状态机的方式。完整的翻译 2012-01-19 11:04:07 · 729 阅读 · 0 评论 -
16.4.4 封装邮箱处理器
16.4.4 封装邮箱处理器 为了封装处理器邮箱,需要把表示处理器的全局值,改成在通常的对象类型内的本地字段。还要添加发送消息到私有邮箱的方法,这也有益于封装:我们不必要公开邮箱可以响应的所有消息,如果有一些仅供内部使用的话。 此更改不需要对消息处理代码做任何修改。在清单 16.17 中,可以看到具体对象类型的声明,处理代码本身则省略了,因为它没有改变。 List翻译 2012-01-18 10:03:36 · 1196 阅读 · 0 评论 -
16.5 消息并发传递
16.5 消息并发传递 当我们在第 14 章中讨论开发并发程序时,关注的技术是避免使用可变状态。没有可变状态,就可以并行地运行一个计算的几个部分,因为它们不会彼此干扰。这在许多能够以函数方式实现的数据处理问题时,工作地非常好,但在处理需要更频繁地交换信息时,也有问题。 最广为人知的解决方案是,使用共享内存(shared memory)和通过锁定保护访问共享的状态。用这种技翻译 2012-01-18 15:28:17 · 748 阅读 · 0 评论 -
16.6 第十六章小结
16.6 第十六章小结 在本章中,我们介绍了函数方式技术开发有响应的应用程序。我们首先讨论在 F# 中的一等事件,把事件当成标准的值使用,可以传递给函数,或从函数返回。这样,可以使用高阶函数(比如,Observable.filter 和 Observable.map)处理事件,使代码更具声明性,与使用高阶函数或 LINQ 查询处理列表的方式相同。 对于更具动态的行为,这种翻译 2012-01-19 16:23:30 · 640 阅读 · 0 评论 -
16.4.3 使用消息进行通信
16.4.3 使用消息进行通信 清单 16.13 创建一个邮箱处理器,statee,类型为 MailboxProcessor。注意,我们创建的 state 方法,是同名的非泛型类的一个成员。我们在 C# 中用来进行类型推断的就是同样的这种模式,在开始将其集成到我们的代码之前,会看到邮箱处理器支持哪些操作。表 16.2 显示了这个泛型类型最重要的实例方法。 Table 16.翻译 2012-01-18 09:20:12 · 772 阅读 · 0 评论 -
16.4.5 等待多个事件
16.4.5 等待多个事件 到目前为止,所有 AwaitObservable 示例中,我们只是等待单个事件发生。矩形绘制应用程序首先等待 MouseDown 事件,然后,反复等待 MouseMove。如果想要等待有,既可能有 MouseMove 事件,也可能一些其他事件发生,又该如何呢?我们可能想要能够以某种方式,放弃绘制的新矩形。我们就来实现这种情况,使用按键作为我们的取消事件。翻译 2012-01-18 11:17:04 · 1098 阅读 · 0 评论 -
13.4.3 收集有关地区的统计信息
13.4.3 收集有关地区的统计信息我们的目标是展示自 1990 年以来,不同地区森林面积的变化。我们需要遍历所有已有的地区,检查数据是否可用,找到下载的指标值。这可以通过使用我们创建的映射,非常轻松地完成,因为已经用年份和地区 ID 作为关键字。 需要小心的是有一些数据可能会缺失,因此,我们要过滤掉所有没有我们需要年份数据的地区。另外,我们还想要显示森林总面积,而不是百分比,因此,在返回数据之前翻译 2017-01-18 18:58:06 · 536 阅读 · 0 评论