是否可以在 F# 中创建惰性事件初始化程序?

Is it possible to make a lazy event initializer in F#?

我有一个服务器通过各种 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)

将打印 'test',所以 Lazy 也有一些我没想到的东西。

惰性构造函数需要一个 lambda Lazy(fun () -> {exp}) 或者您可以使用惰性关键字 lazy {exp}。请注意 {} 只是占位符,而不是计算表达式。

示例:

let p = Lazy<IEvent<string>>(fun () -> (printfn "test"; e.Publish))

或者简单地说:

let p = lazy (printfn "test"; e.Publish)