C# 我是否需要在包装器方法中等待任务

C# 我是否需要在包装器方法中等待任务,c#,asynchronous,async-await,C#,Asynchronous,Async Await,我在Microsoft.Azure.Cosmos.Container类上有一个包装器。 在某些情况下,包装器所做的唯一事情就是调用内部对象的异步方法 public Task<ItemResponse<T>> UpsertItemAsync<T>(T item, PartitionKey? partitionKey = null, ItemRequestOptions requestOptions = null, CancellationToken cancel

我在Microsoft.Azure.Cosmos.Container类上有一个包装器。 在某些情况下,包装器所做的唯一事情就是调用内部对象的异步方法

public Task<ItemResponse<T>> UpsertItemAsync<T>(T item, PartitionKey? partitionKey = null, ItemRequestOptions requestOptions = null, CancellationToken cancellationToken = default)
{
    return _container.UpsertItemAsync<T>(item, partitionKey, requestOptions, cancellationToken);
}
public Task UpsertItemAsync(T item,PartitionKey?PartitionKey=null,ItemRequestOptions-requestOptions=null,CancellationToken-CancellationToken=default)
{
return _container.UpsertItemAsync(item、partitionKey、requestOptions、cancellationToken);
}

在这种情况下,最佳做法是什么?要添加wait before或按原样返回内部对象任务,您必须将async添加到包装器声明中,并等待内部对象任务。。否则,您将无法在稍后的调用方上下文中等待包装器。

这取决于您想要实现什么

这是两个案例

  • 如果在这个包装函数中添加一个wait,那么控件将在那里停止,等待upsert完成。一旦所有的事情都完成了,控制就会返回到调用这个包装器方法的地方

  • 如果您忽略了一个wait,那么现在发生的是这个控件从不等待执行。它使用TPL将异步函数添加到线程池中,TPL基本上在后台运行它。但您从未注意到,代码也从未等待。它继续执行,并立即返回到您呼叫的位置

  • 需要注意的两件事

    如果等待,该行将返回任务结果,可以 int,bool,string或者其他什么

    如果你忽略等待,那条线会 返回一个任务

    这两种方法有许多用例

    • 如果您的调用者需要输出继续,请在此处使用wait
    • 如果你的 调用方只需调用它即可继续(不依赖于此upsert, 让它在后台运行)然后不要使用wait
      • 大卫·福勒()有一个

        我在此复制相关部分:

        与直接返回
        任务相比,更喜欢
        异步
        /
        等待
        使用async/await关键字而不是直接返回任务有很多好处:

        • 异步和同步异常被规范化为始终异步
        • 代码更容易修改(例如,考虑使用
        添加一个
      • 异步方法的诊断更容易(调试挂起等)
      • 抛出的异常将自动包装在返回的任务中,而不会用实际异常使调用方感到意外
      ❌ 此示例直接将任务返回给调用者

      public Task<int> DoSomethingAsync()
      {
          return CallDependencyAsync();
      }
      
      公共任务DoSomethingAsync()
      {
      返回CallDependencyAsync();
      }
      
      ✅ 很好,此示例使用async/await,而不是直接返回任务

      public async Task<int> DoSomethingAsync()
      {
          return await CallDependencyAsync();
      }
      
      public异步任务DoSomethingAsync()
      {
      return wait CallDependencyAsync();
      }
      

      在这种情况下,可以返回任务。但是你必须小心。例如,如果您在try/catch或using块中有此代码,那么您可能希望执行
      wait
      ,这样您就不会在代码完成之前离开这些块。Stephen Cleary对此略知一二。他说,“蔡斯贾德实际上是在最后,他说,当这种方法只是一个过关或超载时,你应该考虑一下。”凯瑟亚德——他在页面上说:“当这个方法只是一个过关或超载时,请考虑一下,”在这种情况下,他所说的是他应该怎么说的。Pivotal的话,认为这是不正确的。您可以等待返回
      Task
      Task
      的任何方法<代码>异步
      仅当您需要在方法中执行
      等待
      时才是必需的。您可以等待返回任务的任何方法,而不管其内部构建的准确程度如何。是的,这取决于您提到的。这一条解释了问题