【问题标题】:Should I always include a synchronous version of a method when I create an async version?在创建异步版本时,我是否应该始终包含方法的同步版本?
【发布时间】:2016-12-20 00:15:56
【问题描述】:

如果我正在为我的团队创建一个将在多个项目之间共享的库,并且该库正在做的工作很适合 async/await,我是否还应该包含非异步/等待版本的代码?似乎有很多重复的代码,但我没有看到任何替代方案。这仅仅是您为提高线程池利用率而付出的代价吗?

为了清楚起见,我不是在问我是否应该包含一个同步包装方法,这是我能够找到答案的全部。

例如,我可能有一个长时间运行的 SQL 查询。然后我需要用两种几乎相同的方法来实现这个接口,一种使用SqlConnectionSqlCommand 上的async 方法,另一种不使用它们。这是正确的方法还是我错过了什么?

public interface ILongRunningOperation
{
    Response LongRunningOperation();

    Task<Response> LongRunningOperationAsync();
}

谢谢!

【问题讨论】:

  • 不。别忘了你也可以使用 LongRunningOperation().Wait(); 的同步形式。以达到相同的结果。这是一个不起眼的扩展,而且经常被忽视。
  • 博客文章Should I expose synchronous wrappers for asynchronous methods? 总结道:“请尽量不要这样做;如果必须,请让您的方法的消费者这样做。您应该考虑有人会使用您的功能的可能性同步,因此相应地编写代码,尽可能少地依赖线程环境。”
  • @JamieMeyer 在提出使用.Wait() 的建议之前,您可能需要重新阅读stackoverflow.com/questions/13140523/…
  • @AlexeiLevenkov 是的,我知道这一点,并同意您参考中接受的答案。这正是我对上述 OP 问题的解释。在所有情况下,该决定都留给读者练习。毕竟,这是一个基于意见的问题。谢谢;-)

标签: c# .net asynchronous async-await


【解决方案1】:

在一般情况下,我会说答案是“否”。自然异步操作(例如,具有 I/O 的操作)最好通过异步 API 来表示。

但是,在某些情况下您可能需要类似的同步 API。向后兼容性是一个常见的原因。另一个是如果您只想提供更简单的同步消费。

如果您决定提供同步 API,我建议您查看 "boolean argument hack" in my MSDN article on brownfield async。您仍然会得到一个同步和异步实现,但它是一种方法,因此您的逻辑不会重复。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-21
    • 2011-06-06
    • 1970-01-01
    • 2011-11-14
    • 2016-08-20
    相关资源
    最近更新 更多