【问题标题】:How to choose methods for async calling in C#, how to propagate async如何在 C# 中选择异步调用的方法,如何传播异步
【发布时间】:2014-06-24 05:40:38
【问题描述】:

我很少有异步编写程序问题的方法。我正在使用一些昂贵的方法编写 WCF 服务,这些方法非常适合异步调用。但我对实施的问题是:

  1. 如果我要在模型中创建异步方法,那么我需要将服务方法标记为异步以便能够等待模型方法,并将返回类型更改为Task<originalType>。这将破坏服务 API 约定的一致性。正确的方法是什么?将服务接口设计为async Task 返回方法是否更好,即使某些方法并不昂贵并且实际上没有理由使其异步?
  2. 据我了解,只有昂贵的方法应该写为异步,但在这种情况下,程序的一半将是同步的,第二个是异步的。对吗?

【问题讨论】:

    标签: c# .net wcf asynchronous async-await


    【解决方案1】:

    如果我要在模型中创建异步方法,那么我需要将服务方法标记为异步,以便能够等待模型方法,并将返回类型更改为任务。这将破坏服务 api 约定的一致性。正确的方法是什么?将服务接口设计为异步任务返回方法是否更好,即使某些方法并不昂贵并且实际上没有理由将其设为异步?

    在 WCF 中,当您更改方法以返回 Task<T> 时,实际上并没有更改 WCF 协定,因为它可以识别单个消息的多个异步模式,这意味着您可以拥有所有 3 种模式(任务、Sync 和 APM)在单个合约界面中,它们都与同一条消息相关。

    来自MSDN

    客户可以为开发人员提供他们选择的任何编程模型,因此 只要观察到底层的消息交换模式。所以,同样, 服务可以以任何方式实现操作,只要 观察到指定的消息模式。

    此主题在Different forms of the WCF service contract interfaceAsynchronously consume synchronous WCF service 中得到扩展

    据我了解,只有昂贵的方法应该写为异步,但在这种情况下,程序的一半将是同步的,第二个是异步的。对吗?

    正如@l3arnon 所说,公开async api 不是关于方法有多“昂贵”,而是关于方法调用所做的工作。如果它是真正的异步工作,例如访问文件系统、发送网络请求、访问外部数据源(例如数据库),那么这就是公开异步 api 的合适人选。

    将这些事实与 WCF 相结合,您可以通过单个合同公开同步和异步方法。

    【讨论】:

    • 被选为与问题最匹配的答案。但所有答案都非常有用。谢谢你们。
    【解决方案2】:

    当有一种“昂贵”的方法时,我不会说你需要async-await。当有真正异步操作(主要是 IO 调用)时,更好的指导方针是使用async-await

    如果您有许多这样的操作,那么在整个运行时保持线程将是一种浪费,并且会严重阻碍可伸缩性。这是一种权衡,您需要自己决定什么对您来说更重要:简单性还是可扩展性。

    如果您的应用程序是一个富客户端,那么可伸缩性可能并不重要,WCF 服务中我会始终如果可以,请选择异步选项。

    【讨论】:

    • 在 GUI 应用程序中,您不希望阻止 UI 线程进行长时间运行的同步(例如 CPU 绑定)操作,因此在此处使用类似 await Task.Run() 的东西是有意义的。但同样不适用于 WCF 服务等。
    • @svick 确实。 WCF 服务中的async-await 是关于可伸缩性的,而在 GUI 应用程序中则是关于卸载的。
    【解决方案3】:
    1. 调用者无法检测到您选择使服务方法同步还是异步。合同不变。 TaskIAsyncResult 无论如何都不能通过 SOAP 序列化,因此不可能将 Task 传输到客户端。 I have explained this extensively before.
    2. 不是“昂贵”,而是长期运行的 IO 绑定。服务器上异步的好处是避免线程被阻塞。这暂时节省了 1MB 的堆栈空间和一个线程池插槽。如果您不需要此增益,并且大多数工作负载不需要,请不要使用异步。从开发的角度来看,异步并非免费。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-03-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-03-17
      • 1970-01-01
      • 1970-01-01
      • 2016-07-20
      相关资源
      最近更新 更多