ASP.NET Core 效能最佳實踐(一)
阿新 • • 發佈:2020-09-18
這篇文章的主要內容來源於.NET文件,此處翻譯前4條內容,其他內容會陸續貼出來
- 儘量使用快取
- 瞭解”熱程式碼路徑”
- 避免使用阻塞呼叫
- 返回值使用IEnumerable<T> 或 IAsyncEnumerable<T>
儘量使用快取
詳情請檢視:ASP.NET Core 中的響應快取.
瞭解”熱程式碼路徑”
”熱程式碼”定義為訪問頻繁並且耗時較長的程式碼。”熱程式碼”對效能影響很明細。
避免使用阻塞呼叫
ASP.NET Core 程式應該被設計成同時處理多個請求。非同步API使用一個小執行緒池可以處理上千個併發請求,而不會阻塞。這樣請求執行緒可以去處理其他請求,而不是等待一個長時同步任務完成。
ASP.NET Core 程式的一個常見的效能問題是,阻塞了本該非同步執行的呼叫。很多同步呼叫會導致執行緒池飢餓,增大相應時間。
不要像下面這樣做:
- 通過Task.Wait或Task.Result阻塞非同步執行。
- 在常用程式碼上使用鎖(lock)。ASP.NET Core 程式被設計為並行架構時執行效率最高。
- 自己定義一個Task.Run,然後去await。由於ASP.NET Core 程式已經是在通用執行緒池上運行了,呼叫 Task.Run 是沒有必要的,
應該這樣做:
- 非同步呼叫“熱程式碼”。
- 在訪問資料,I/O,長時操作的時候,如果有非同步API就儘量使用非同步API。不要使用Task.Run將同步API非同步執行。
- 使Controller或Razor Page中的Action非同步化。將整個呼叫棧非同步化,以便使用 async/await。
效能分析器PerfView,可以用來查詢頻繁加入執行緒池的執行緒。
Microsoft-Windows-DotNETRuntime/ThreadPoolWorkerThread/Start 表明一個執行緒加入了執行緒池。
返回IEnumerable<T> 還是 IAsyncEnumerable<T>
如果Action Result返回IEnumerable<T>,那麼序列化器以同步的方式處理集合迭代,這樣阻塞呼叫可能會導致執行緒池飢餓,為避免同步迭代,可在返回迭代之前呼叫ToListAsync()。
從ASP.NET Core 3.0開始,IAsyncEnumerable<T>作為非同步列舉,可取代IEnumerable<T>。