繁体   English   中英

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

[英]Do I need to await a task in a wrapper method

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

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);
}

在这种情况下,最佳做法是什么? 在之前添加等待或按原样返回内部 object 任务?

这取决于您想要达到的目标。

这是2个案例。

  1. 如果您在此包装器 function 中添加等待 - 控件将停在那里等待 upsert 完成。 一切完成后,控制权就会从调用此包装器方法的位置返回

  2. 如果您忽略等待 - 现在会发生此控件从不等待执行。 它使用 TPL 将异步 function 添加到线程池,该线程池基本上在后台运行。 但是您永远不会注意到,代码也永远不会等待。 它继续执行并立即返回您调用的位置

2个注意事项

如果您等待它,该行将返回任务结果,可以是 int、bool、string 或其他

如果您忽略等待,该行将返回一个任务

这两种方法有很多用例。

  • 如果您的来电者需要 output 才能继续,请在此处使用 await
  • 如果你的调用者只是调用它并且可以继续(不依赖于这个 upsert,让它在后台运行)那么不要使用 await

David Fowler ( ASP.NET Architect ) 有很好的指导

我在这里复制相关部分:

优先使用async / await而不是直接返回 Task 使用 async/await 关键字而不是直接返回Task有好处:

  • 异步和同步异常被规范化为始终是异步的。
  • 代码更容易修改(例如,考虑添加using )。
  • 异步方法的诊断更容易(调试挂起等)。
  • 抛出的异常将自动包装在返回的 Task 中,而不是让调用者惊讶于一个实际的异常。

❌ BAD 这个例子直接将Task返回给调用者。

public Task<int> DoSomethingAsync()
{
    return CallDependencyAsync();
}

✅ 好 这个例子使用 async/await 而不是直接返回 Task。

public async Task<int> DoSomethingAsync()
{
    return await CallDependencyAsync();
}

注意:使用异步 state 机器而不是直接返回Task时,有性能考虑。 直接返回Task总是更快,因为它做的工作更少,但你最终会改变行为并可能失去异步 state 机器的一些好处。

您必须将异步添加到您的包装器声明并等待您的内部 object 任务..否则您将无法稍后在调用者上下文中等待您的包装器..

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM