最近在学习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.AwaitTask
和Async.StartAsTask
)交互,甚至可以使用Async.StartWithContinuations 轻松创建自己的异步操作
.要了解有关异步工作流程的更多信息,您可以查阅MSDN documentation ,宏伟Scott Wlaschin's site , Tomas Petricek's blog或F# Wikibook .
Control.MailboxProcessor
:设计用于处理并发,即多个进程同时运行,通常需要共享一些信息。当多个线程尝试同时写入变量时,防止内存损坏的传统 .NET 方法是 lock 语句。除了函数式风格更喜欢使用不可变值这一事实之外,内存锁的正确使用也很复杂,而且还会带来很高的性能损失。因此,MailboxProcessor
使用类似 Erlang 的基于消息(或基于 actor)的并发方法来代替这种方法。我自己并没有太多使用
MailboxProcessor
,但有关更多信息,您可以查看 Scott Wlaschin's site或F# Wikibook .
我希望这有帮助!如果有人发现此答案不完全正确,请随时进行编辑。
干杯!
关于concurrency - F# 并发的不同方法之间的关系是什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27663122/