2017-03-08 58 views
1

我正在遷移當前正在同步並將其移至異步/等待的ASP.NET中相當大的一段代碼。我所看到的大部分建議都是從堆棧中遷移出來的,所以基本上就是一次使用霰彈槍的方法。將ASP.NET代碼從同步部分遷移到異步/等待

爲了降低風險,我想限制多少代碼同時改變的範圍,但這意味着我需要從同步方法調用異步代碼以避免代碼重複。

我做了一些搜索,發現Stephen Cleary的Nito.AsyncEx NuGet包中有一個AsyncContext.Run方法,可以啓用這種類型的異步代碼包裝。

下面是我如何考慮進行遷移的示例。遺留代碼會調用GetContent,它是同步的,現在只是GetContentAsync方法的包裝。這使我可以靈活地從遺留代碼中調用同步方法,但我不能隨時更改,但同時允許我在任何地方使用異步代碼。

我的問題是,這看起來像一個可行的方法嗎?同步包裝方法是否存在任何缺陷或潛在的性能問題?其他人如何應對將大型代碼庫遷移到異步的挑戰?

using Nito.AsyncEx; 
using System.Net.Http; 
using System.Threading.Tasks; 

namespace AsyncMigration 
{ 
    public class ContentManager 
    { 
     public string GetContent(string url) 
     { 
      return AsyncContext.Run(() => GetContentAsync(url)); 
     } 

     public async Task<string> GetContentAsync(string url) 
     { 
      HttpClient client = new HttpClient(); 
      return await client.GetStringAsync(url); 
     } 
    } 
} 

回答

0

AsyncContext做什麼是隊列中的所有呼叫,並依次執行它們。在本質上。

你會進一步傷害你的性能,因爲AsyncContext需要一個額外的線程來執行你的異步代碼,同時阻止當前的線程。被叫時。您的同步方法將從Web服務器的線程池中取出一個線程。此同步方法將阻止AsyncContext.Run,​​使其線程不可用於處理新的調用。反過來,AsyncContext將從線程池中取出另一個線程來完成工作。

換句話說,與AsyncContext相比,您浪費了比使用純同步調用更多的線程。