.NET 4.5 引入 async/await 簡化非同步編程,但許多文章混淆概念。本文釐清 ASP.NET 非同步模型核心要素。
ThreadPool.GetMaxThreads 取得工作執行緒與 I/O 完成埠執行緒上限。工作執行緒處理一般請求,資源有限;I/O 執行緒處理非同步 I/O(檔案、網路、資料庫),通常閒置。Task、ThreadPool、async/await 為實作工具,非同步本質在於「釋放工作執行緒」。正確(使用 HttpClient 真正非同步 I/O):
public async Task<string> Get() {
return await GetArticleContentAsync();
}
private async Task<string> GetArticleContentAsync() {
using (var httpClient = new HttpClient()) {
var response = await httpClient.GetAsync("https://www.asp.net");
var buffer = await response.Content.ReadAsByteArrayAsync();
return Encoding.UTF8.GetString(buffer);
}
}
錯誤(Task.Run 包裝同步封鎖呼叫):
public async Task<string> GetArticleContentByNoRigntWayAsync() {
return await Task.Run(() => {
using (var client = new WebClient()) {
return client.DownloadString("https://www.asp.net");
}
});
}
後者仍佔用工作執行緒執行同步封鎖 I/O,未釋放執行緒,ASP.NET 環境下無法提升吞吐量,甚至因執行緒切換增加開銷。
結論:必須使用原生非同步 API(HttpClient、SqlCommand.ExecuteReaderAsync、Stream.ReadAsync 等)搭配 async/await,才能真正發揮非同步效能優勢。