我什么时候应该使用 Async.AwaitIAsyncResult 而不是 Async.AwaitTask 来等待任务?

When should I use Async.AwaitIAsyncResult instead of Async.AwaitTask to await a Task?

我想在使用以下调用保存更改时等待 Entity Framework Core 返回的 Task<int>myDbContext.SaveChangesAsync true

我发现了至少 3 种不同的实现方法,但我不确定哪种方法最好,因为我并不真正关心 Task<int> 中的 int 结果部分,在一天结束的时候,我只想等待。

使用 Async.AwaitIAsyncResult 然后 Async.AwaitIgnore 忽略 Task<bool>:

async {
    do! myDbContext.SaveChangesAsync true
    |> Async.AwaitIAsyncResult
    |> Async.AwaitIgnore
}

Task<int> 升级为 Task 然后等待 TaskAsync.AwaitTask:

async {
    do! myDbContext.SaveChangesAsync true
    :> Task
    |> Async.AwaitTask
}

等待 Task<int> Async.AwaitTask 并忽略 Async.Ignore

的结果
async {
    do! myDbContext.SaveChangesAsync true
    |> Async.AwaitTask
    |> Async.Ignore
}

AwaitIAsyncResult 如果我想在等待任务时获取一个布尔值以防出错(和/或我想通过超时控制执行),那么

AwaitIAsyncResult 似乎更相关:https://msdn.microsoft.com/en-us/visualfsharpdocs/conceptual/async.awaitiasyncresult-method-%5Bfsharp%5D?f=255&MSPPError=-2147217396.我也怀疑这是正确的,如果我想避免在等待时出现问题的情况下抛出异常并取而代之的是获取布尔值。

剩下另外两个解决方案,我想说最后一个更好地解释了我不关心 Task<int> / Async<int>.[=34 的 int 的意图=]

但是我不太确定,有人可以验证或否定我的想法吗?

接口 IAsyncResult 是 .NET 异步早期遗留下来的(记住 FileStream.BeginRead/FileStream.EndRead),因此它仅在与遗留 API 互操作时使用。

Async.AwaitIAsyncResult returns Async<bool> 并不意味着它以任何方式处理异常,事实上它没有。

所以 Async.AwaitIAsyncResult 不碍事,我会说你的第三个例子

async {
    do! myDbContext.SaveChangesAsync true
    |> Async.AwaitTask
    |> Async.Ignore
}

是要走的路,因为意图是明确的。

我看不出你的例子是如何编译的,所以我希望我没有遗漏任何东西。

我想这就是我的处理方式:

open FSharp.Control.Tasks.V2 // From nuget package Taskbuilder.fs

let someExampleAsync (thing: bool) : Threading.Tasks.Task<int> = 
    task {
        printfn "this got called"
        return 1
    }

let saveChanges() : Async<int> = someExampleAsync true |> Async.AwaitTask

// await once
saveChanges() |> Async.RunSynchronously |> ignore

// await a few times
let repeatIt = 
    async {
        let! awaitOnce = saveChanges()
        let! awaitAgain = saveChanges()
        let! awaitAndAgain = saveChanges()
        return "all done"
    }

repeatIt |> Async.RunSynchronously |> ignore

免责声明:我是初学者。