File.ReadAllLinesAsync()
會阻塞UI執行緒非同步方法理想情況下在返回待處理任務之前執行最少的同步工作。 然而,File.ReadAllLinesAsync()
並不總是遵循這種最佳實踐。
問題:
該方法可能會在非同步操作實際開始之前意外地阻塞 UI 執行緒相當長的一段時間。
最初的誤解:
最初假設阻塞源自於檔案系統操作固有的同步性質。 然而,測試表明線程在發生任何文件訪問之前阻塞。
真正的問題:
File.ReadAllLinesAsync()
的實現並未完全擁抱非同步原則。它在移交任務之前執行大量同步預處理。
建議解決方案:
為了防止 UI 執行緒阻塞,請使用 File.ReadAllLines()
包裹的同步 Task.Run()
方法進行非同步執行:
<code class="language-csharp">var lines = await Task.Run(() => File.ReadAllLines(@"D:\temp.txt"));</code>
效能比較:
使用 6MB 檔案進行的測試顯示 File.ReadAllLinesAsync()
在傳回未完成的任務之前阻塞了大約 450 毫秒(然後在 5 毫秒內完成)。 相反,當透過 Task.Run()
非同步運行時,同步方法的延遲可以忽略不計。
.NET 6 及更高版本:
雖然 .NET 6 為 File.ReadAllLinesAsync()
帶來了性能改進,但在非同步使用時它仍然比同步方法慢,並且沒有完全展現真正的異步行為。 因此,將 Task.Run()
與同步方法結合使用仍然是獲得最佳 UI 回應能力的建議方法。
以上是儘管是異步的,為什麼「File.ReadAllLinesAsync()」會阻塞 UI 執行緒?的詳細內容。更多資訊請關注PHP中文網其他相關文章!