如何在普通任务上的Async.AwaitTask(不是任务<t>)?</t>

时间:2011-11-05 20:02:56

标签: f# async-await

我正在尝试在F#中使用C#库。该库大量使用async / await。我想在F#中的async { ... }工作流程中使用。

我看到我们可以Async.AwaitTask返回Task<T>的异步C#方法,但那些返回普通Task的方法呢?

也许,是否有帮助将这些转换为Async<unit>或将Task转换为Task<unit>,以便它可以与Async.AwaitTask一起使用?

4 个答案:

答案 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)