首页 > 解决方案 > 移植出队 - 将循环从 C# 添加到 F#

问题描述

我正在尝试移植这个简单的循环:

    var messages = new List<string>();
    while (_MessageQueue.TryDequeue(out var message))
        messages.Add(message);

消息队列是并发的。它用于将来自多个线程的消息排入队列的模块中,然后由单个线程处理它们。

是否有一种惯用的 F# 方法来执行出队/添加循环?

标签: c#f#

解决方案


F# 有几种实现并发的方法,包括对基于代理的编程的良好支持,因此您所做的惯用 F# 版本很可能实际上不会使用并发队列,而是基于代理或一些其他架构。

但是,要回答您关于循环的具体问题 - C# 版本非常简洁,这要归功于巧妙地使用whileand out var。在 F# 中,您可以调用TryDequeue作为bool与值一起返回的方法(这样我们可以避免突变)。我会将它与递归序列表达式一起使用:

let mq = System.Collections.Concurrent.ConcurrentQueue<int>()

let rec readAll () = seq {
  let succ, msg = mq.TryDequeue() 
  if succ then
      yield msg
      yield! readAll() }

let messages = readAll() |> List.ofSeq

该函数定义了一个调用readAll序列 ( ),如果操作成功,它会将消息添加到结果中,然后使用递归尝试读取更多消息。IEnumerableTryDequeueyield msgyield!


推荐阅读