【问题标题】:When should I use Async.AwaitIAsyncResult instead of Async.AwaitTask to await a Task?我什么时候应该使用 Async.AwaitIAsyncResult 而不是 Async.AwaitTask 来等待任务?
【发布时间】:2023-04-07 03:44:01
【问题描述】:

在使用以下调用保存更改时,我想等待 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
}

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

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

AwaitIAsyncResult 似乎更相关,如果我想在等待任务时获取一个布尔值以防出错(和/或我想通过超时来控制执行):https://msdn.microsoft.com/en-us/visualfsharpdocs/conceptual/async.awaitiasyncresult-method-%5Bfsharp%5D?f=255&MSPPError=-2147217396。我也怀疑这是正确的,如果我想避免在等待时出现问题而将异常抛出到我的脸上,而是获取一个布尔值。

剩下的还有其他两个解决方案,我想说最后一个更好地表达了我不关心Task<int> / Async<int>int 的意图。

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

【问题讨论】:

    标签: f# async-await task f#-async


    【解决方案1】:

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

    Async.AwaitIAsyncResult 返回Async<bool> 的事实并不意味着它以任何方式处理异常,事实上它不会。

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

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

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

    【讨论】:

      【解决方案2】:

      我看不到您的示例将如何编译,所以我希望我不会在这里遗漏一些东西。

      我认为这就是我要解决的问题:

      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
      

      免责声明:我是初学者。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-01-28
        • 2016-08-09
        • 2011-12-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-08-27
        相关资源
        最近更新 更多