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

  • 相关阅读:
    巨人的崛起 Android操作系统发展历程
    iPhone 4S定位功能加强 支持GLONASS系统
    android子线程更新UI,与主Thread一起工作
    什么在阻碍移动互联网的普及?
    WEB.CONFIG 配置详解
    解决在aspx页面上进行传中文参数时会出现乱码问题
    VS2005水晶报表注册码
    windows2003应用程序池假死的问题
    浅谈ASP.NET内部机制
    合理建立数据库索引
  • 原文地址:https://www.cnblogs.com/Alex80/p/7802878.html
Copyright © 2020-2023  润新知