我正在学习线程,任务和异步编码,并尝试将这些概念应用于我每天工作的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()并保持代码的原样。
答案 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;
}
- 这是正确的,以便在执行I / O时释放应用程序池中的线程以进行其他工作吗?
醇>
没有。你正在做的事情真的没有意义。你根本不会让这些调用异步。
如果您使用await
,那么是的,您确实可以获得异步操作的好处(即释放UI线程)。
- 我是否需要以不同方式处理异常?
醇>
如果您正在使用await
,那么不,您的现有代码可以正常使用。如果您使用的是Result
,那么您的所有例外情况都将包含在AggregateException
中。
- Close()和Abort()是否仍然必要且相关?
醇>
是
答案 1 :(得分:0)
如果调用异步版本并等待完成比常规方式更好,框架可以透明地为您执行此操作。它没有这样做的事实表明这种方法并不好。
如果我使用等待,那么我需要将堆栈中的每个方法标记为async,这样做更多。
这就是交易。您必须更改整个调用堆栈,因为您的线程必须在IO运行时将控制权返回给线程池。您必须退出堆栈上的所有功能。感谢上帝async / await使这主要是一个机械练习。
出于这个原因,你应该在响应中使用async / await 来满足你无法获得的性能需求。默认情况下不要使用它。首先确定你现在是否真的有太多的线程。如果不是,你很可能根本不需要异步。把时间投入其他地方。