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的。不然,别人调用时很容易踩着这个坑,然后就一直等啊等。。。等到花儿谢了,电脑冒烟了,也等不到。

【相关链接】

async & await 的前世今生

Best Practices in Asynchronous Programming

Don't Block on Async Code

ASP.NET sync over async(异步中同步,什么鬼?)

最新文章

  1. 51nod1135(求最小原根)
  2. js框架设计1.4类型判断
  3. 赞!带进度条的 jQuery 文件拖放上传插件
  4. Stickup – 轻松实现元素固定效果的 jQuery 插件
  5. 【XLL API 函数】 xlDefineBinaryName
  6. How to Create Mixed Reality Videos for the Vive - with Two Controllers
  7. Android_ADB 常用 shell命令 和 sqlite3 简单增删改查
  8. python_文件
  9. Servlet 3.0 之@WebFilter怎么控制多个filter的执行顺序
  10. xcode 预编译头文件
  11. Android如何在一个线性布局里完美显示两个listview啊?
  12. 作品第二课----点击DIV显示其内容
  13. Android 字体颜色变化(点击)
  14. LeetCode_Palindrome Partitioning II
  15. 35,000FT大气压力的问题
  16. win10下Python3.6安装、配置以及pip安装包教程
  17. python入门编程之三级菜单编程
  18. MongoDB自学(3)
  19. 通过CSS自动截取字符串长度
  20. Linux--信号阻塞与屏蔽

热门文章

  1. Ubuntu中文乱码问题解决方案
  2. .net中反射技术的应用
  3. .net获取本地ip地址
  4. Proxmox Reset Root Password
  5. 关于部署传统的Dynamic Web项目
  6. 2017/2/10:Manven简介与项目管理(入门)
  7. Vue.directive基础,在Vue模块开发中使用
  8. Rest架构风格的实践(使用通用Mapper技术)
  9. 744. Find Smallest Letter Greater Than Target
  10. [转]图解CSS的padding,margin,border属性(详细介绍及举例说明)