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

Ash*_*eyF 35 f# async-await

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

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

或许,是否有帮助将这些转换为Async<unit>或转换TaskTask<unit>可以使用Async.AwaitTask

zeu*_*xcg 46

你可以使用ContinueWith:

let awaitTask (t: Task) = t.ContinueWith (fun t -> ()) |> Async.AwaitTask
Run Code Online (Sandbox Code Playgroud)

或AwaitIAsyncResult具有无限超时:

let awaitTask (t: Task) = t |> Async.AwaitIAsyncResult |> Async.Ignore
Run Code Online (Sandbox Code Playgroud)

  • 啊,我明白了.当然,Task毕竟是IAsyncResult.缩写为`let awaitTask = Async.AwaitIAsyncResult >> Async.Ignore`非常感谢! (10认同)

Dav*_*ave 15

更新:

F#4.0的FSharp.Core库现在包含一个Async.AwaitTask接受普通的重载Task.如果你使用F#4.0,那么你应该使用这个核心功能而不是下面的代码.


原始答案:

如果您的任务可能抛出异常,那么您可能还想检查这一点.例如

let awaitTask (task : Task) =
    async {
        do! task |> Async.AwaitIAsyncResult |> Async.Ignore
        if task.IsFaulted then raise task.Exception
        return ()
    }
Run Code Online (Sandbox Code Playgroud)


Wal*_*lly 11

我真的很喜欢Ashley使用函数组合的建议.此外,您可以像这样扩展Async模块:

module Async =
    let AwaitTaskVoid : (Task -> Async<unit>) =
        Async.AwaitIAsyncResult >> Async.Ignore
Run Code Online (Sandbox Code Playgroud)

然后它与Async.AwaitTask一起出现在Intellisense中.它可以像这样使用:

do! Task.Delay delay |> Async.AwaitTaskVoid
Run Code Online (Sandbox Code Playgroud)

有关更好名字的任何建议吗?