5

代わりにとTcpClientを使用して、いくつかの依存コードを.net4.5に移植しようとしています。StreamSocketDataReader

ReadLine()どこでも使われているという名前の関数があります。このコードDataReaderの本文( )で使用することにより、私のメソッドはキーワードでマークされるように強制されます。LoadAsync()async

連鎖反応は次のとおりです。これで、呼び出しメソッドに追加し、基になるメソッド呼び出しasyncに待機を適用する必要がある場所が何百もあります。async

これは私の次の質問につながります...ReadLine()呼び出し元のメソッドがそれが非同期メソッドであることを認識しないようにラップする簡単な方法はありますか?それでコードの残りの部分を変更する必要はありませんか?

また...私はこのメソッド呼び出しを複数の場所からループで使用することがよくあります。これらのメソッドが現在マークされている場合async、私はそうすべきではないときにストリームからデータを読み取っている可能性があり、それはあらゆる種類の悪夢を引き起こすでしょう。それは問題ですか、それとも私はあまりにも先を考えていますか?

4

3 に答える 3

8

また...私はこのメソッド呼び出しを複数の場所からループで使用することがよくあります。これらのメソッドが非同期としてマークされている場合は、すべきでないときにストリームからデータを読み取っている可能性があります。これにより、あらゆる種類の悪夢が発生します。それは問題ですか、それとも私はあまりにも先を考えていますか?

awaitメソッドを呼び出すときに常に使用する場合*Asyncasyncメソッドは同期メソッドと同じように機能します(ブロックされないことを除いて)。したがってawait、ループでの使用は、期待どおりに機能します。


async実際、コードベースを通じて「成長」します。私は通常、これを「カメがずっと下がっている」という昔の話に似ていると思います。他の人はそれを「ゾンビウイルス」と呼んでいます。

デッドロックの状況については、ブログで詳しく説明しています。私がそこで述べているように、最良の選択肢はasync成長を可能にすることです。

非同期メソッドの同期ラッパーを作成する必要がある場合は、StephenToubのアドバイスを参照してください。を使用できますTask.Resultが、次の2つのことを行う必要があります。

  • ConfigureAwait(false)どこでも使用できます。これにより、デッドロック状態が回避されます。
  • Resultエラー処理のセマンティクスが異なることに注意してください。

あなたの特定の例では、このようなもので十分です:

private async Task<string> ReadLineAsync()
{
  ... // *Every* await in this method and every method it calls
      // must make use of ConfigureAwait(false).
}

public string ReadLine()
{
  try
  {
    return ReadLineAsync().Result;
  }
  catch (AggregateException ex)
  {
    ExceptionDispatchInfo.Capture(ex.InnerException).Throw();
    throw;
  }
}

同期/非同期の混合コードベースを選択する前に、複雑さを慎重に検討してください。最初に表示されるほど簡単ではありません。

PS一般的に言って、TCP/IPコードはとにかくすべて非同期である必要があります。通常、ソケットで継続的な非同期読み取りを実行することをお勧めします。

于 2013-01-07T02:20:51.313 に答える
2

ReadLineAsync関数とReadLine関数を作成します。
ReadLine関数では、次のようにReadLineAsyncを呼び出すことができます。

var readLineTask = ReadLineAsync(); 
readLineTask.Wait() 
于 2013-01-06T19:51:10.003 に答える
0

非同期としてマークすることは、あなたがそれを呼び出すときはいつでもそれを待たなければならないという意味ではありません。メソッド内でawaitを使用したため、非同期としてマークしています。

つまり、他のメソッドを呼び出すという理由だけで、他のメソッドを非同期としてマークする必要はありませんReadLine()

readlineメソッドが待機可能であるためには、Taskまたはを返す必要がありTask<T>ます。

于 2013-01-06T19:53:45.373 に答える