3

次の拡張メソッドがあります。

internal static string ReadLine(this DataReader stream)
{
   Task<string> line = ReadLineAsync(stream);
   // line.Wait(); - Not Required, as next call blocks
   return line.Result;
}

これは基本的に、文字列を返す非同期メソッド呼び出しの同期メソッド呼び出しラッパーです。コードを 1 行ずつ実行すると問題なく動作しますが、自由に実行させると不定ブロックに遭遇するようです。何か案は?

私が投稿した以前の質問に関連する: How can I update my API to use the async keyword without using await for all caller

4

2 に答える 2

10

他の質問への回答にコメントされているようTask.Resultに、GUI アプリケーションで使用すると、デッドロックが発生する可能性があります(ブログで詳しく説明しています)。

要するに:

  • UI スレッドで非同期操作を開始します。タスクはメソッドをline表し、そのReadLineAsyncメソッドが完了すると完了することに注意してください。
  • ReadLineAsyncawait不完全な操作を呼び出します。これによりReadLineAsync、不完全なタスクが返されます ( line)。
  • 完了するのを待っている UI スレッドをブロックしlineます。
  • ed 操作が完了するawaitと、残りの操作ReadLineAsyncが UI スレッドにスケジュールされます。
  • UI スレッドは、完了するのをReadLineAsync待って同期的にブロックされているためReadLineAsync、完了できません。デッドロック。

このデッドロックを回避する方法については、他の質問に対する私の回答を参照してください。要するに:

  • ConfigureAwait(false)どこでも使用できます。
  • Resultでエラーをラップすることを考慮して、エラー処理を変更しますAggregateException
于 2013-01-07T02:30:09.707 に答える