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

  • 相关阅读:
    第二阶段冲刺--第五天
    git托管代码随笔--运用ssh传输,不用每次提交频繁输入github账号密码
    项目冲刺--第十天
    项目冲刺--第九天
    随堂练习--用例图练习
    项目冲刺--第四天
    第五次个人作业: 案例分析--微软必应词典客户端
    Code.R团队展示
    Android 自定义AlertDialog
    Ubuntu打开系统监视器查看进程&资源等信息
  • 原文地址:https://www.cnblogs.com/Alex80/p/7802878.html
Copyright © 2011-2022 走看看