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

问题描述 投票:1回答:1

我有一个通过各种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也没有我期望的东西。

events f# lazy-evaluation
1个回答
0
投票

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

示例:

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

或简单地:

let p = lazy (printfn "test"; e.Publish)
© www.soinside.com 2019 - 2024. All rights reserved.