程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> ASP.NET >> 關於ASP.NET >> 如何在現有代碼中通過async/await實現並行

如何在現有代碼中通過async/await實現並行

編輯:關於ASP.NET

一項新技術或者一個新特性,只有你用它解決實際問題後,才能真正體會到它的魅力,真正理解它。也期待大家能夠多分享解一些解決實際問題的內容。

在我們遭遇“黑色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實現並行。

需要注意的地方:

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果然好用!

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved