1

私は疑問に思っていました...

新しい非同期コンストラクトは、コンシューマー側で新しいコードを記述せずに、実際に中間結果を可能にしますか?

例を挙げて詳しく説明します。

データをバイト配列またはストリームのどちらか良い方にダウンロードするメソッドがあるとしましょう。

組み込みの非同期機能を使用してダウンロードが完了する前に、そのawaitメソッドがバイト配列またはストリームの消費を開始する可能性はありますか?私にできることは、ストリームの特定の部分がダウンロードされるたびにイベントを発生させることですが、それは再び混乱を増やします。

awaitedメソッドがそのような結果を返すことを考えると、中間結果が得られると期待するコード例(頭のてっぺんから、正しいコードではありません!)を書いてみましょう。

io.Stream data = await downloadData();
byte[4096] buffer = new byte[4096];
while (!data.EOF) {
  (await?) data.Read(buffer, offset, 4096);
}

今のところ、待ちきれませんStream.Readが、これを行う方法はありますか?乗り換えができるようになりたいです。私は何かを監督していますか?await

4

2 に答える 2

2

Stream.Net 4.5で使用している場合は、次のReadAsync()方法を使用できます。

Stream stream = await downloadData();
byte[4096] buffer = new byte[4096];
int read;
do
{
    read = await stream.ReadAsync(buffer, 0, buffer.Length);
    // do something with buffer here
} while (read > 0);

ストリームになどのメソッドがないが、パターンReadAsync()を使用した非同期をサポートしていて、を使用したい場合は、次のようにすることもできます。BeginXxx()EndXxx()await

do
{
    read = await Task.Factory.FromAsync<byte[], int, int, int>(
        stream.BeginRead, stream.EndRead, buffer, 0, buffer.Length, null);
    // do something with buffer here
} while (read > 0);

ただし、同期Read()メソッドしかない場合、それを使用する唯一の方法は、バックグラウンドスレッドasyncで新しいメソッドを開始することです。Task

do
{
    read = await Task.Run(() => stream.Read(buffer, 0, buffer.Length));
    // do something with buffer here
} while (read > 0);

このコードの問題は、それでもスレッドをブロックすることです。これはasync回避しようとしていることです。ただし、メソッドがGUIスレッドで実行され、ループ全体をバックグラウンドスレッドで実行できない場合は、それでも役立つ可能性があります。

于 2012-05-11T11:28:41.110 に答える
2

良い例を示すにはあまり詳しくありませんが、1回限りの結果ではなく、複数の結果が必要なように思われるため、観察可能に適しているように思われます。ここにリンクの説明を入力すると、Rxチームの2.0ベータブログ投稿からの画像がこれらの線に沿って非常に役立ちます(IMHO)。

ここに画像の説明を入力してください

于 2012-05-11T19:22:57.367 に答える