我正在尝试在F#中使用C#库。该库大量使用async / await。我想在F#中的async { ... }
工作流程中使用。
我看到我们可以Async.AwaitTask
返回Task<T>
的异步C#方法,但那些返回普通Task
的方法呢?
也许,是否有帮助将这些转换为Async<unit>
或将Task
转换为Task<unit>
,以便它可以与Async.AwaitTask
一起使用?
答案 0 :(得分:44)
您可以使用ContinueWith:
let awaitTask (t: Task) = t.ContinueWith (fun t -> ()) |> Async.AwaitTask
或具有无限超时的AwaitIAsyncResult:
let awaitTask (t: Task) = t |> Async.AwaitIAsyncResult |> Async.Ignore
答案 1 :(得分:14)
<强>更新强>
F#4.0的FSharp.Core库现在包含一个接受普通Async.AwaitTask
的{{1}}重载。如果你正在使用F#4.0,那么你应该使用这个核心功能而不是下面的代码。
原始回答:
如果你的任务可能抛出异常,那么你可能也想检查一下。 e.g。
Task
答案 2 :(得分:10)
我真的很喜欢Ashley使用函数组合的建议。此外,您可以像这样扩展Async模块:
module Async =
let AwaitTaskVoid : (Task -> Async<unit>) =
Async.AwaitIAsyncResult >> Async.Ignore
然后它与Async.AwaitTask一起出现在Intellisense中。它可以像这样使用:
do! Task.Delay delay |> Async.AwaitTaskVoid
有关更好名字的任何建议吗?
答案 3 :(得分:1)
为了正确地传播异常和取消,我认为你需要这样的东西(部分基于TomášPetříček删除的答案):
module Async =
let AwaitVoidTask (task : Task) : Async<unit> =
Async.FromContinuations(fun (cont, econt, ccont) ->
task.ContinueWith(fun task ->
if task.IsFaulted then econt task.Exception
elif task.IsCanceled then ccont (OperationCanceledException())
else cont ()) |> ignore)