1

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

到目前为止,我有:

  • 像这样配置的服务参考:

配置服务参考

  • 更改了客户端调用

    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() 是否仍然必要且相关?
4

2 回答 2

1

我直接调用结果以在任务上隐式调用 .Wait() 并基本保持代码不变。

我完全不推荐这个。在一般情况下,调用ResultWaitasync代码中会导致死锁(正如我在博客中解释的那样)。由于实现方法的方式,它可能(当前)起作用svcutil,但我不建议进入编写这样的代码的实践。

async允许通过代码库增长要好得多:

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

不,你在做什么真的没有意义。您根本不会让调用是异步的。

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

  1. 我需要以不同的方式处理异常吗?

如果您使用的是await,那么不,您现有的代码可以正常工作。如果您使用Result的是 ,那么是的,您的所有异常都将包含在AggregateException.

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

是的。

于 2013-09-19T00:38:30.697 回答
0

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

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

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

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

于 2013-09-18T22:59:55.497 回答