简体   繁体   English

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

[英]Converting synchronous WCF service client calls to asynchronous

I'm learning about Threading, Tasks and asynchronous coding and am trying to apply the concepts to Web Forms applications I work on daily. 我正在学习线程,任务和异步编码,并试图将这些概念应用于我每天工作的Web窗体应用程序。

So far I have: 到目前为止,我有:

  • Configured Service reference like so: 配置的服务参考如下:

配置服务参考

  • Changed client calls from 来自的客户电话已更改

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

to

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

I am calling the result directly to implictly call .Wait() on the task and keep the code largely as is. 我直接调用结果来隐式地在任务上调用.Wait()并在很大程度上保持代码不变。

  1. Is this correct in order to free up threads in the app pool for other work whilst doing I/O? 为了在执行I / O时释放应用程序池中的线程用于其他工作,这是否正确?
  2. Do I need to handle exceptions differently? 我是否需要以不同的方式处理异常?
  3. Are Close() and Abort() still necessary and relevant? 还需要Close()和Abort()吗?

I am calling the result directly to implictly call .Wait() on the task and keep the code largely as is. 我直接调用结果来隐式地在任务上调用.Wait()并在很大程度上保持代码不变。

I don't recommend this at all. 我根本不建议这样做。 In the general case, calling Result or Wait in async code can cause deadlocks (as I explain on my blog). 在一般情况下, async代码中调用ResultWait会导致死锁 (正如我在博客中所解释的)。 It may work (currently) due to the way svcutil is implementing the methods, but I don't recommend getting into the practice of writing code like this. 由于svcutil实现方法的方式,它可能(当前)有效,但是我不建议您开始编写这样的代码。

It's much better to allow async to grow through the code base: 允许async通过代码库增长更好:

MyServiceClient msc = new MyServiceClient();
try
{
     myData = await msc.GetDataAsync();                    
     msc.Close();
}
catch (Exception)
{
     msc.Abort();
     throw;
}
  1. Is this correct in order to free up threads in the app pool for other work whilst doing I/O? 为了在执行I / O时释放应用程序池中的线程用于其他工作,这是否正确?

No. There is really no point to what you're doing. 不。您的工作真的没有意义。 You're not letting the calls be asynchronous at all. 您根本不让调用异步。

If you use await , then yes, you do get the benefits of asynchronous operations (ie, freeing up the UI thread). 如果使用await ,那么可以,您确实会获得异步操作的好处(即释放UI线程)。

  1. Do I need to handle exceptions differently? 我是否需要以不同的方式处理异常?

If you're using await , then no, your existing code would work fine. 如果您使用的是await ,那么不会,您现有的代码可以正常工作。 If you're using Result , then yes, all your exceptions will be wrapped in an AggregateException . 如果使用的是Result ,那么可以,所有异常都将包装在AggregateException

  1. Are Close() and Abort() still necessary and relevant? 还需要Close()和Abort()吗?

Yes. 是。

If calling the async version and waiting for completion was better than the normal way, the framework could just do this transparently for you. 如果调用异步版本并等待完成比正常方式更好,那么框架可以为您透明地进行此操作。 The fact that it doesn't do that shows you that this approach is not good. 它没有做到这一点的事实向您表明这种方法不好。

If I use await I then need to mark each method up the stack as async which is much more work. 如果我使用await,则需要将堆栈中的每个方法标记为异步,这需要更多工作。

That's the deal. 就是这样 You have to change the entire call stack because your thread has to return control to the thread pool while the IO is running. 您必须更改整个调用堆栈,因为在IO运行时,线程必须将控制权返回给线程池。 You must exit all function on the stack. 您必须退出堆栈上的所有功能。 Thank god async/await makes this mostly a mechanical exercise. 谢谢上帝,异步/等待使这主要是机械锻炼。

For that reason you should use async/await in response to a performance need that you otherwise cannot get. 因此,您应该使用async / await 来响应您否则无法获得的性能需求。 Do not use it by default. 默认情况下不使用它。 First determine, whether you actually have too many threads at the moment or not. 首先确定当前是否实际有太多线程。 If not you very likely do not need async at all. 如果不是这样,您极有可能根本不需要异步。 Invest your time elsewhere. 在其他地方投资时间。

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

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