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 ファイルを使用した テストでは、不完全なタスク (その後 5 ミリ秒で完了) を返す前に、約 450 ミリ秒間の File.ReadAllLinesAsync()
ブロックが発生しました。 逆に、同期メソッドは、Task.Run()
経由で非同期的に実行された場合、無視できるほどの遅延を示しました。
.NET 6 以降:
.NET 6 は File.ReadAllLinesAsync()
のパフォーマンスを向上させましたが、非同期で使用すると同期アプローチよりも遅いままであり、真の非同期動作を完全には発揮しません。 したがって、UI の応答性を最適化するには、同期メソッドで Task.Run()
を使用することが推奨されるアプローチとなります。
以上が`File.ReadAllLinesAsync()` が非同期であるにもかかわらず UI スレッドをブロックするのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。