【发布时间】:2020-06-07 13:05:32
【问题描述】:
我有一个通过各种 RabbitMQ 交换推送一些数据的服务器。
在客户端(有多个客户端使用来自服务器的不同数据流组合),我有一个用作接口的通用库。
当该公共库与 rabbit 建立联系时,它将为每个交换创建一个侦听器队列并公开客户端可以订阅的事件。因此,实际上每个客户都在监听所有的交换,即使他们只需要一些数据。
部分初始化代码如下所示:
RabbitSubscriber(ExchangeChannel.ConsoleInfo.channelName exchange, fun x -> JsonConvert.DeserializeObject<string>(x) |> consoleInfoEvent.Trigger) |> ignore
RabbitSubscriber(ExchangeChannel.ConsoleError.channelName exchange, fun x -> JsonConvert.DeserializeObject<string>(x) |> consoleErrorEvent.Trigger) |> ignore
RabbitSubscriber(ExchangeChannel.Messages.channelName exchange, fun x -> JsonConvert.DeserializeObject<string>(x) |> messageEvent.Trigger) |> ignore
...
大概有 15 个交易所。
我想弄清楚的是,是否有一种方法可以检测客户端何时想要订阅与特定交换相关的事件(例如第一行中的 consoleInfoEvent)并仅在存在时初始化队列订阅。
事件是这样暴露的:
member this.OnConsoleInfoEvent = consoleInfoEvent.Publish
member this.OnConsoleErrorEvent = consoleErrorEvent.Publish
member this.OnConnectionEvent = connectionEvent.Publish
...
在这种情况下,我可以反转客户端注册时的情况,(通过 .OnConsoleInfoEvent.Add...)我会初始化客户端队列。
这可以结合事件和懒惰吗?还是有更好的机制?
当我试图让发布者变得懒惰时,代码会立即执行:
let e = Event<string>()
let p = Lazy<IEvent<string>>(printfn "test"; e.Publish)
将打印“测试”,因此 Lazy 也有一些我没有想到的东西。
【问题讨论】:
-
惰性构造函数需要一个 lambda
Lazy(fun () -> exp)或者您可以使用惰性关键字lazy {exp}。 -
@gus,我让它与 lambda 一起工作。谢谢!计算表达式的语法是什么?我试过 Lazy
> { return! e.Publish } 但它不会编译。 -
是的,它不是 CE,我写的括号具有误导性。我将其转换为答案。
标签: events f# lazy-evaluation