如何在C#中选择异步调用方法,如何传播异步

时间:2014-06-24 05:40:38

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

我几乎没有编写程序问题的异步方式。我正在用一些昂贵的方法编写WCF服务,这些方法非常适合异步调用。但我对这些实现的疑问是:

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

3 个答案:

答案 0 :(得分:5)

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

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

如果您的应用程序是富客户端,可能的可扩展性 重要,WCF服务中我总是如果可以,请选择异步选项。

答案 1 :(得分:5)

  

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

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

来自MSDN

  

客户可以为开发人员提供他们选择的任何编程模型,所以   只要观察到基础消息交换模式。所以,也是,   只要服务,服务可以以任何方式实施操作   观察到指定的消息模式。

本主题适用于Different forms of the WCF service contract interfaceAsynchronously consume synchronous WCF service

  

据我所知,只有昂贵的方法应该写成async,但在这种情况下,程序的一半将是同步的,第二个是异步的。是不是?

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

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

答案 2 :(得分:2)

  1. 调用者无法检测您是否选择使服务方法同步或异步。合同没有变化。无论如何,TaskIAsyncResult都不能通过SOAP进行序列化,因此不可能将Task传输到客户端。 I have explained this extensively before.
  2. 不是&#34;昂贵&#34;,但长期运行IO限制。服务器上异步的增益是保护线程不被阻止。此临时可节省1MB的堆栈空间和一个线程池插槽。如果您不需要此增益,并且大多数工作负载不需要,请不要异步。从开发的角度来看,异步并不是免费的。