我有一个异步执行某些操作的函数,但是没有公开异步,而是在完成时调用带有结果的回调。我想把它变成异步,并提出了这个代码,但似乎并不合适。有没有更好的方法呢?
async {
let ev = Event<_>()
someAsyncExternalCodeThatWillCallTheCallbackWhenDone(fun value -> ev.Trigger value)
let! value = Async.AwaitEvent(ev.Publish)
return value
}
在这种情况下使用Observable或ManualResetEvent而不是Event的任何优势?
答案 0 :(得分:4)
我认为这种情况下的惯用解决方案是使用Async.FromContinuations
:
Async.FromContinuations(fun (cont, econt, ccont) ->
someAsyncExternalCodeThatWillCallTheCallbackWhenDone(cont))
FromContinuations
函数还允许您处理异常(如果发生异常,则调用econt
)或取消(您可以将其视为基本方法来创建异步计算)。
那就是说,我认为使用事件没有任何问题。带有事件的代码实现了几乎相同的逻辑(我认为),但是以更复杂的方式实现。