async/task/await
2017-11-08 10:45
429 查看
async/task/await三组合是.NET Framework 4.5带给.NET开发者的大礼,合理地使用它,可以提高应用程序的吞吐能力。
但是它的使用有点绕人,如果不正确使用,会带来意想不到的问题——比如await之后一直在等待,等到花儿也谢了,也等不来。
这篇博文将向你展示我们在实际开发中遇到的这个问题。
先看一段ASP.NET MVC示例代码:
代码说明:
在上面的代码中,虽然在Action方法之前加了async Task<ActionResult>,但由于在方法体中没有使用await,所以实际还是以同步的方式执行的,与直接使用ActionResult是一样的。
GetResponseHtml是同步方法,GetResponseContentAsync是异步方法,在GetResponseHtml中调用了异步的GetResponseContentAsync。(如果调用的是第三方程序集,我们就不知道在GetResponseHtml中进行了异步调用,所以这个方法的设计是有问题的)
这段代码执行结果会是怎样呢?
——结果就是没有结果,一直在执行。。。
(注:如果在控制台应用程序中调用同样的GetResponseHtml,不会出现这个问题)
那如果解决这个问题呢:
解决方法一:在MVC Action中开启一个Task进行await
解决方法二:将GetResponseHtml变成异步方法
显然,第2个解决方法是更好的。
所以,我们在设计一个方法(method)时,如果调用了async方法,一定要将这个方法本身设计为async的。不然,别人调用时很容易踩着这个坑,然后就一直等啊等。。。等到花儿谢了,电脑冒烟了,也等不到。
但是它的使用有点绕人,如果不正确使用,会带来意想不到的问题——比如await之后一直在等待,等到花儿也谢了,也等不来。
这篇博文将向你展示我们在实际开发中遇到的这个问题。
先看一段ASP.NET MVC示例代码:
public class BlogController : Controller { public async Task<ActionResult> AwaitDemo() { var responseHtml = GetResponseHtml("http://www.cnblogs.com/"); return Content(responseHtml); } private string GetResponseHtml(string url) { return GetResponseContentAsync(url).Result; } private async Task<string> GetResponseContentAsync(string url) { var httpClient = new System.Net.Http.HttpClient(); var response = await httpClient.GetAsync(url); if (response.StatusCode == System.Net.HttpStatusCode.OK) { return await response.Content.ReadAsStringAsync(); } else { return "error"; } } }
代码说明:
在上面的代码中,虽然在Action方法之前加了async Task<ActionResult>,但由于在方法体中没有使用await,所以实际还是以同步的方式执行的,与直接使用ActionResult是一样的。
GetResponseHtml是同步方法,GetResponseContentAsync是异步方法,在GetResponseHtml中调用了异步的GetResponseContentAsync。(如果调用的是第三方程序集,我们就不知道在GetResponseHtml中进行了异步调用,所以这个方法的设计是有问题的)
这段代码执行结果会是怎样呢?
——结果就是没有结果,一直在执行。。。
(注:如果在控制台应用程序中调用同样的GetResponseHtml,不会出现这个问题)
那如果解决这个问题呢:
解决方法一:在MVC Action中开启一个Task进行await
public async Task<ActionResult> AwaitDemo() { var responseHtml = await Task.Factory.StartNew(() => GetResponseHtml("http://www.cnblogs.com/")); return Content(responseHtml); }
解决方法二:将GetResponseHtml变成异步方法
public async Task<ActionResult> AwaitDemo() { var responseHtml = await GetResponseHtml("http://www.cnblogs.com/"); return Content(responseHtml); } private async Task<string> GetResponseHtml(string url) { return await GetResponseContentAsync(url); }
显然,第2个解决方法是更好的。
所以,我们在设计一个方法(method)时,如果调用了async方法,一定要将这个方法本身设计为async的。不然,别人调用时很容易踩着这个坑,然后就一直等啊等。。。等到花儿谢了,电脑冒烟了,也等不到。
相关文章推荐
- C#中 Thread,Task,Async/Await,IAsyncResult 的那些事儿!
- async,await本质以及与Task的关系。
- C# Task中的Func, Action, Async与Await的使用
- Thread,Task,async/await,IAsyncResult
- .NET(C#):await返回Task的async方法
- C#中 Thread,Task,Async/Await,IAsyncResult 的那些事儿!
- async/await Task Timeout
- 第二十三节: EF性能篇(三)之基于开源组件 Z.EntityFrameWork.Plus.EF6解决EF性能问题 第四节:一些指令总结 定时调度系列之Quartz.Net详解 第十七节:易混淆的概念(静态和非静态、拆箱和装箱) 那些年我们一起追逐的多线程(Thread、ThreadPool、委托异步调用、Task/TaskFactory、Parallerl、async和await)
- 线程--线程池--委托--task---async/await
- C#异步 Thread、Task、Async/Await、IAsyncResult
- 【多线程】 Task ,async ,await
- C#异步Async、Task、Await
- C#的Task、async、await关键字
- async和await用法(Task)
- Task async/await
- C# Task中的Func, Action, Async与Await的使用
- async/task/await
- C# Async await和Task的关系
- .net Async await Task<T>
- 异步方法的意义何在,Async和await以及Task的爱恨情仇,还有多线程那一家子。