【问题标题】:Is it possible to make a lazy event initializer in F#?是否可以在 F# 中创建惰性事件初始化程序?
【发布时间】: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 () -&gt; exp) 或者您可以使用惰性关键字 lazy {exp}
  • @gus,我让它与 lambda 一起工作。谢谢!计算表达式的语法是什么?我试过 Lazy> { return! e.Publish } 但它不会编译。
  • 是的,它不是 CE,我写的括号具有误导性。我将其转换为答案。

标签: events f# lazy-evaluation


【解决方案1】:

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

例子:

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

或者简单地说:

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

【讨论】:

  • 我不知道“懒惰”是一个关键字,我使用的是“懒惰”。谢谢!
  • 我将如何使用它?我不能 p.Force 返回一个 IEvent,但我不能做 p.Force.Add(...)?
  • 您可以通过p.Value访问底层价值,从那里您可以访问.Add(和其他方法。
  • 行得通,谢谢!那么与Force有什么区别?我以为他们都会返回值,因为这个线程 stackoverflow.com/questions/7569310/… 似乎暗示。
  • 是一样的,唯一的区别是Value是一个值(或属性),Force是一个函数(或方法)。因此,如果您使用Force,则必须将()p.Force().Add( 一样。我更喜欢使用Value
猜你喜欢
  • 2012-12-15
  • 2015-05-24
  • 1970-01-01
  • 1970-01-01
  • 2022-08-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-20
相关资源
最近更新 更多