我最近学习了F#异步工作流,这是F#并发的一个重要特性。令我感到困惑的是,在F#中编写并发代码的方法有多少?我读了除F#以及一些关于F#并发的博客,我知道像背景工作者这样的东西; IAsyncResult的;如果在本地机器上编程,则F#中存在shard-memory并发;如果在分布式系统上编程,则存在消息传递并发。但我真的不确定这些技术之间的关系是什么,以及如何对它们进行分类。我知道这是一个很大的"大"问题无法用一两句话回答,所以如果有人能给我具体答案或推荐一些有用的参考资料,我绝对会感激。
答案 0 :(得分:1)
我对F#也很陌生,所以我希望能有更多的答案来补充这个:)
首先,您需要区分 .NET类(可以从任何.NET语言使用)和 F#唯一方式来处理异步操作。在你提及的第一种情况中,你有:
System.ComponentModel.BackgroundWorker
:这主要用于Windows Forms的第一个.NET版本,不再推荐使用。
System.IAsyncResult
:这也是由几个类(也是Task)实现的旧.NET接口,但我通常不会直接使用它。
Windows.Foundation.IAsyncOperation
:另一个界面,但仅在Windows应用商店应用中使用。大多数情况下,您将其直接翻译为任务,因此您不必过于担心它。
System.Threading.Tasks.Task
:这是现在处理.NET异步和并行(使用并行任务库)操作的推荐方法。它是C#async / await关键字背后的隐藏力量,它只是将连续性传递给任务的语法糖。
现在使用 F#独特方式:异步工作流程和 MailboxProcessor 。可以粗略地说,前者对应于并行性,而后者则涉及并发性。
Asynchronous Workflows
:这只是一个计算表达式(又名monad),它碰巧处理异步:在后台运行以防止阻塞UI线程或并行操作以获得最大性能的操作多核系统。
它或多或少等同于C#async / await但我们F#粉丝喜欢认为它是一个更优雅的解决方案,因为它使用更通用和灵活的机制(计算表达式),可以适应例如{{3} },asynchronous sequences甚至events。托马斯·彼得林克解释Javascript callbacks时还有其他优点。
在异步工作流程中,大部分时间您将使用Control.Async
中的方法或来自F#Core Library的.NET类扩展(如WebRequest.AsyncGetResponse
)。如有必要,您还可以直接与.NET任务(Async.AwaitTask
和Async.StartAsTask
)进行交互,甚至可以使用Async.StartWithContinuations
轻松创建自己的异步操作。
要详细了解异步工作流程,您可以参考here,宏伟的MSDN documentation,Scott Wlaschin's site或Tomas Petricek's blog。
Control.MailboxProcessor
:旨在处理并发性,即通常需要共享某些信息的同时运行的多个进程。当多个线程同时尝试写入变量时,传统的.NET防止内存损坏的方法是lock语句。除了功能样式更喜欢使用不可变值之外,内存锁使用起来很复杂并且还可能具有很高的性能损失。因此,MailboxProcessor
使用类似Erlang的基于消息的(或基于actor的)并发方法来代替这一点。
我自己没有使用MailboxProcessor
那么多,但有关详细信息,您可以查看F# Wikibook或Scott Wlaschin's site。
我希望这有帮助!如果有人在此答案中看到一些不完全正确的内容,请随时进行编辑。
干杯!