将同步WCF服务客户端调用转换为异步

时间:2013-09-18 20:19:24

标签: c# wcf asynchronous

我正在学习线程,任务和异步编码,并尝试将这些概念应用于我每天工作的Web窗体应用程序。

到目前为止,我有:

  • 配置服务参考如下:

Configure Service Reference

  • 更改了客户来电
    MyServiceClient msc = new MyServiceClient();
    try
    {
         myData =  msc.GetData();                    
         msc.Close();
    }
    catch (Exception)
    {
         msc.Abort();
         throw;
    }
    

    MyServiceClient msc = new MyServiceClient();
    try
    {
         myData =  msc.GetDataAsync().Result;                    
         msc.Close();
    }
    catch (Exception)
    {
         msc.Abort();
         throw;
    }

我直接调用结果来暗示在任务上调用.Wait()并保持代码的原样。

  1. 这是正确的,以便在执行I / O时释放应用程序池中的线程以进行其他工作吗?
  2. 我是否需要以不同方式处理异常?
  3. Close()和Abort()是否仍然必要且相关?

2 个答案:

答案 0 :(得分:1)

  

我直接调用结果来暗示在任务上调用.Wait()并保持代码的原样。

我根本不推荐这个。在一般情况下,calling Result or Wait in async code can cause deadlocks(正如我在我的博客上解释的那样)。它可能(目前)由于svcutil实现方法的方式而起作用,但我不建议开始编写这样的代码。

允许async通过代码库增长更好:

MyServiceClient msc = new MyServiceClient();
try
{
     myData = await msc.GetDataAsync();                    
     msc.Close();
}
catch (Exception)
{
     msc.Abort();
     throw;
}
  
      
  1. 这是正确的,以便在执行I / O时释放应用程序池中的线程以进行其他工作吗?
  2.   

没有。你正在做的事情真的没有意义。你根本不会让这些调用异步。

如果您使用await,那么是的,您确实可以获得异步操作的好处(即释放UI线程)。

  
      
  1. 我是否需要以不同方式处理异常?
  2.   

如果您正在使用await,那么不,您的现有代码可以正常使用。如果您使用的是Result,那么您的所有例外情况都将包含在AggregateException中。

  
      
  1. Close()和Abort()是否仍然必要且相关?
  2.   

答案 1 :(得分:0)

如果调用异步版本并等待完成比常规方式更好,框架可以透明地为您执行此操作。它没有这样做的事实表明这种方法并不好。

  

如果我使用等待,那么我需要将堆栈中的每个方法标记为async,这样做更多。

这就是交易。您必须更改整个调用堆栈,因为您的线程必须在IO运行时将控制权返回给线程池。您必须退出堆栈上的所有功能。感谢上帝async / await使这主要是一个机械练习。

出于这个原因,你应该在响应中使用async / await 来满足你无法获得的性能需求。默认情况下不要使用它。首先确定你现在是否真的有太多的线程。如果不是,你很可能根本不需要异步。把时间投入其他地方。