concurrency - F# 并发的不同方法之间的关系是什么

标签 concurrency f#-async

最近在学习F#异步工作流程,这是F#并发的一个重要特性。让我困惑的是,在 F# 中编写并发代码有多少种方法?我读过除了 F# 和一些关于 F# 并发的博客,我了解诸如后台工作人员之类的东西; IAsyncResult;如果在本地机器上编程,F#中存在分片内存并发;如果在分布式系统上编程,就会存在消息传递并发性。但我真的不确定这些技术之间有什么关系,以及如何对它们进行分类。我知道这是一个相当“大”的问题,无法用一两句话来回答,所以如果有人能给我具体的答案或推荐一些有用的引用资料,我将不胜感激。

最佳答案

我对 F# 也很陌生,所以我希望有更多答案来补充这个答案:)

首先,您需要区分 .NET 类(可以在任何 .NET 语言中使用)和F# 独特方法来处理异步操作。在您提到的第一种情况以及其他情况下,您有:

  • System.ComponentModel.BackgroundWorker:这主要在带有 Windows 窗体的第一个 .NET 版本中使用,不再推荐使用。

  • System.IAsyncResult:这也是一个旧的.NET接口(interface),由多个类(也是Task)实现,但我通常不直接使用它。

  • Windows.Foundation.IAsyncOperation:另一个接口(interface),但仅在 Windows 应用商店应用中使用。大多数时候你直接把它翻译成Task,所以你不用太担心。

  • System.Threading.Tasks.Task:这是现在处理 .NET 异步和并行(使用并行任务库)操作的推荐方法。这是 C# async/await 关键字背后的隐藏力量,这些关键字只是将延续传递给任务的语法糖。


现在使用F# 独特的方式:异步工作流MailboxProcessor。大致可以说,前者对应的是并行,后者对应的是并发。

  • 异步工作流:这只是一个计算表达式(又名 monad),它恰好处理异步:在后台运行的操作,以防止阻塞 UI 线程或并行操作来获取多核系统中的最高性能。

    它或多或少相当于 C# async/await,但我们 F# 粉丝喜欢认为这是一个更优雅的解决方案,因为它使用更通用和灵活的机制(计算表达式),例如可以适应 asynchronous sequences , events甚至Javascript callbacks 。正如 Thomas Petricek 所解释的那样,它还具有其他优点 here .

    在异步工作流程中,大多数时候您将使用 Control.Async 中的方法或 .NET 类的扩展(例如 WebRequest.AsyncGetResponse) F# 核心库。如有必要,您还可以直接与 .NET 任务(Async.AwaitTaskAsync.StartAsTask)交互,甚至可以使用 Async.StartWithContinuations 轻松创建自己的异步操作.

    要了解有关异步工作流程的更多信息,您可以查阅MSDN documentation ,宏伟Scott Wlaschin's site , Tomas Petricek's blogF# Wikibook .

  • Control.MailboxProcessor:设计用于处理并发,即多个进程同时运行,通常需要共享一些信息。当多个线程尝试同时写入变量时,防止内存损坏的传统 .NET 方法是 lock 语句。除了函数式风格更喜欢使用不可变值这一事实之外,内存锁的正确使用也很复杂,而且还会带来很高的性能损失。因此,MailboxProcessor 使用类似 Erlang 的基于消息(或基于 actor)的并发方法来代替这种方法。

    我自己并没有太多使用MailboxProcessor,但有关更多信息,您可以查看 Scott Wlaschin's siteF# Wikibook .


我希望这有帮助!如果有人发现此答案不完全正确,请随时进行编辑。

干杯!

关于concurrency - F# 并发的不同方法之间的关系是什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27663122/

相关文章:

java - 并发 CPLEX 进程比单个进程慢很多

asynchronous - HttpClient 的超时在异步 block 内不起作用

exception-handling - Async.Await未捕获任务异常

concurrency - Sinatra + websocket + 赛璐珞

java - 基准测试 : Same process multiple times, 只有一个预热?

java - 具有约束的 Java 中的并发请求处理

f# - 为什么计算表达式不跨越finally block

asynchronous - 如何在 F# 的异步工作流中使用重新加注?

F# 在 Async.Catch 上继续

node.js - 在 React 应用程序中的多个输入文件上运行 ffmpeg (WASM/NodeJS)