events - 在 F# 中同时等待多个事件中的任何一个事件

标签 events f# asynchronous

在 F# 中,我知道如何使用 Async.AwaitEvent 异步等待一个事件:

let test = async {
  let! move = Async.AwaitEvent(form.MouseMove)
  ...handle move... }

假设我想等待 MouseMoveKeyDown事件。我想要这样的东西:

let! moveOrKeyDown = Async.AwaitEvent(form.MouseMove, form.KeyDown)

这个函数不存在,但是还有其他方法吗?

最佳答案

我使用了您在talk about reactive programming中的示例中使用的方法的实现。我在伦敦拥有的(页面底部有一个下载链接)。如果您对这个主题感兴趣,您可能会发现这次演讲也很有用:-)。

我使用的版本采用 IObservable 而不是 IEvent(因此该方法的名称为 AwaitObservable)。将 Event.merge(以及 Event 模块中的其他组合器)与 AwaitEvent 一起使用时,会出现一些严重的内存泄漏>,所以你应该使用 Observable.merge 等和 AwaitObservable 代替。

问题描述更详细here (参见第 3 节以获得清晰的示例)。简而言之 - 当您使用 Event.merge 时,它会将处理程序附加到源事件(例如 MouseDown),但在您使用 等待完成后,它不会删除该处理程序>AwaitEvent,因此该事件永远不会被删除 - 如果您在使用异步工作流编码的循环中继续等待,您就会不断添加新的处理程序(运行时不会执行任何操作)。

一个简单的正确解决方案(基于 desco 发布的内容)如下所示:

let rec loop () = async {
  let e1 = f.KeyDown |> Observable.map Choice1Of2
  let e2 = f.MouseMove |> Observable.map Choice2Of2
  let! evt = Observable.merge e1 e2 |> Async.AwaitObservable
  // ...
  return! loop() } // Continue looping

顺便说一句:您可能还想查看this article (基于我书中的第 16 章)。

关于events - 在 F# 中同时等待多个事件中的任何一个事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3701861/

相关文章:

c# - 从触发的事件中提取数据

c# - WPF 应用程序的内容调整大小事件

F# - JSON 类型提供程序 - 文字字符串

python - 从python中的异步函数修改全局变量

javascript - 如何监听双击jstree?

javascript - 在鼠标事件之间传递数据

haskell - 是否可以将 F# 记录的标签用作 Haskell 中的函数或类似的函数?

ios - 如何在返回值之前等待关闭完成

java - 垂直x。在一次调用 update() 中执行多次插入