zoukankan      html  css  js  c++  java
  • 在现有代码中通过async/await实现并行

    在现有代码中通过async/await实现并行

    一项新技术或者一个新特性,只有你用它解决实际问题后,才能真正体会到它的魅力,真正理解它。也期待大家能够多分享解一些解决实际问题的内容。

    在我们遭遇“黑色30秒”问题的过程中,切身体会到了异步的巨大作用(详见从ASP.NET线程角度对“黑色30秒”问题的全新分析),于是开始逐步地用async/await改造现有代码。

    今天早上在将一个MVC Controller中的Action改为异步的时候突然发现——其中有7个方法调用可以并行执行。

    public async Task<ActionResult> BlogPostInfo(string blogApp, int blogId, int postId, Guid blogUserGuid)
    {
        //7个方法无关联的方法调用 
    }

    如果通过async/await实现了这7个方法的并行,性能将会提高几倍,真是一个意外的惊喜!

    惊喜之后,则要面对这样一个问题——如何以最低的成本实现?

    这7个方法其他地方也在调用,不想直接把这些方法改为异步的;即使可以改为异步的,也不想一路改到底,最后在数据访问层调用ADO.NET的异步方法。

    。。。

    接着在园子里发现了另外一个惊喜——Jesse Liu博文(async & await 的前世今生)中的一张图片:

    async/await实现并行

    好帅的图!连执行顺序都标得清清楚楚。只要照着这张图,就可以轻松地用async/await实现并行。

    需要注意的地方:

    1)并行调用的目标方法必须是async的。

    2)在并行期间,不能使用await。

    以下是实现案例: 

    下面的代码是需要并行执行的7个方法中的2个:

    复制代码
    var tags = TagService.GetTag(blogId, postId);
    if (!string.IsNullOrEmpty(tags))
    {
        info.Tags = string.Format("标签: {0}", TagService.GetTagLink(blogUrl, tags));
    }                
    
    var categories = CategoryService.GetCateList(blogUrl, blogId, postId);
    if (!string.IsNullOrEmpty(categories))
    {
        info.Categories = "分类: " + categories;
    }
    复制代码

    由于并行调用的目标方法必须是async的,并且我们不想修改原有的方法实现代码,所以我们增加2个async方法中转一下:

    async方法1:

    public static async Task<string> GetTagAsync(int blogId, int entryId)
    {
        return await Task.Run(() => { return GetTag(blogId, entryId); });
    }

    async方法2:

    public static async string GetCateListAsnyc(string blogUrl, int blogId, int entryId)
    {
        return await Task.Run(() => { return GetCateList(blogUrl, blogId, entryId); });
    }

    然后在调用代码中,分别调用这2个async方法让其并行执行,之后再用await取执行结果。

    复制代码
    var tagsTask = TagService.GetTagAsync(blogId, postId);
    var categoriesTask = BlogCategoryService.GetCateListAsync(blogUrl, blogId, postId);
    
    var tags = await tagsTask;
    if (!string.IsNullOrEmpty(tags))
    {
        info.Tags = string.Format("标签: {0}", TagService.GetTagLink(null, blogUrl, tags));
    }           
    
    var categories = await categoriesTask;
    if (!string.IsNullOrEmpty((categories)))
    {
        info.Categories = "分类: " + categories;
    }
    复制代码

    真的很简单,很轻松! async/await果然好用!

     
     
     
    标签: C#async
  • 相关阅读:
    做技术选型时,要注意些什么?
    .net core 实现默认图片
    启用跨源请求 (CORS)
    使用 Cookie 而无需 ASP.NET 核心标识的身份验证
    Windbg+Procdump解决w3wp.exe CPU过百问题
    .NET Core 2.0 Cookie中间件 权限验证
    想要学习设计模式,你得先会看类图,一张图读懂UML
    ef core
    Dapper MySql DateTime 异常
    简单理解Socket
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/3717660.html
Copyright © 2011-2022 走看看