async/task/await
async/task/await三组合是.NET Framework 4.5带给.NET开发者的大礼,合理地使用它,可以提高应用程序的吞吐能力。
但是它的使用有点绕人,如果不正确使用,会带来意想不到的问题——比如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的。不然,别人调用时很容易踩着这个坑,然后就一直等啊等。。。等到花儿谢了,电脑冒烟了,也等不到。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)