質問

C#(およびVB)の新しいASYNC機能と.NET 4.0の間で違いはありません タスクパラレルライブラリ. 。たとえば、Eric Lippertのコードを考えてみましょう ここから:

async void ArchiveDocuments(List<Url> urls) {
    Task archive = null;
    for(int i = 0; i < urls.Count; ++i) {
        var document = await FetchAsync(urls[i]);
        if (archive != null)
            await archive;
        archive = ArchiveAsync(document);
    }
}

そうです await キーワードは2つの異なる目的を果たしています。最初の出来事(FetchAsync)意味するようです、 「この値が使用されている場合 メソッドの後半 そして、そのタスクは終了しません。継続する前に完了するまで待ちます。」 2番目のインスタンス(archive)意味するようです、 「このタスクがまだ終わっていない場合は、待ってください たった今 それが完了するまで。」 私が間違っているなら、私を修正してください。

このように簡単に書くことはできませんでしたか?

void ArchiveDocuments(List<Url> urls) {
    for(int i = 0; i < urls.Count; ++i) {
        var document = FetchAsync(urls[i]);       // removed await
        if (archive != null)
            archive.Wait();                       // changed to .Wait()
        archive = ArchiveAsync(document.Result);  // added .Result
    }
}

最初のものを交換しました await とともに Task.Result 値が実際に必要であり、2番目の値が必要です awaitTask.Wait(), 、待機が実際に発生している場所。機能はです (1) すでに実装されています (2) コードで実際に起こっていることにより意味的にははるかに近い。

私はそれを理解しています async メソッドは、イテレーターと同様の状態マシンとして書き換えられますが、どのような利点がもたらすかはわかりません。操作するために別のスレッドを必要とするコード(ダウンロードなど)には別のスレッドが必要になり、(ファイルからの読み取りなど)がないコードは、単一のスレッドのみで動作するためにTPLを使用することができます。

ここでは明らかに大きなものがありません。誰かが私がこれをもう少しよく理解するのを手伝ってくれますか?

役に立ちましたか?

解決

ここで誤解が生じていると思います。

待ち望まれているキーワードは、2つの異なる目的を果たしているようです。最初の発生(Fetchasync)は、「この値がメソッドの後半で使用され、そのタスクが終了しない場合、継続する前に完了するまで待ってください」を意味するようです。 2番目のインスタンス(アーカイブ)は、「このタスクがまだ終了していない場合は、完了するまで今すぐ待ってください」を意味しているようです。私が間違っているなら、私を修正してください。

これは実際には完全に正しくありません。これらは両方と同じ意味を持っています。

あなたの最初のケースで:

var document = await FetchAsync(urls[i]);

ここで起こることは、ランタイムが「Fetchasyncを呼び出し始めてから、現在の実行ポイントをこの方法を呼び出すスレッドに戻す」と書かれているということです。ここには「待機」はありません - 代わりに、実行は呼び出し同期コンテキストに戻り、物事はかき回し続けます。将来のある時点で、Fetchasyncのタスクは完了し、その時点で、このコードは呼び出しスレッドの同期コンテキストで再開され、次のステートメント(ドキュメント変数の割り当て)が発生します。

その後、2回目の待望の呼び出しまで実行が続きます - その時点で、同じことが起こります - Task<T> (アーカイブ)は完全ではなく、実行は呼び出しコンテキストにリリースされます - それ以外の場合、アーカイブが設定されます。

2番目のケースでは、事態は非常に異なります - ここでは、明示的にブロックしています。つまり、通話同期コンテキストは、メソッド全体が完了するまでコードを実行する機会を得ることはありません。確かに、まだ非同期がありますが、非同期はこのコードのブロック内に完全に含まれています。このスレッドの外側のコードは、すべてのコードが完了するまで発生しません。

他のヒント

大きな違いがあります:

Wait() ブロック、 await ブロックしません。 Asyncバージョンを実行した場合 ArchiveDocuments() GUIスレッドでは、GUIはフェッチとアーカイブの操作が実行されている間、応答性を維持します。 TPLバージョンを使用する場合 Wait(), 、GUIはブロックされます。

ご了承ください async スレッドを導入せずにこれを行うことができます - await, 、コントロールは単にメッセージループに戻されます。待機中のタスクが完了すると、メソッドの残り(継続)がメッセージループに囲まれ、GUIスレッドは実行され続けます ArchiveDocuments 中断したところ。

アンダースは、彼がしたチャンネル9ライブインタビューで非常に簡潔な答えにそれを煮詰めました。強くお勧めします

新しいAsyncと待望のキーワードは、あなたを許可します 同時性を調整します アプリケーションで。彼らは実際にあなたのアプリケーションに並行性を導入しません。

TPL、より具体的にはタスクです 一方通行 実際に操作を同時に実行するために使用できます。新しいAsyncと待望のキーワードは、あなたを許可します 構成します 「同期」または「線形」ファッションでのこれらの同時操作。

したがって、実際のコンピューティングが同時に発生する場合とそうでない場合がありますが、プログラムに線形制御の流れを書き込むことができます。計算が同時に発生した場合、待ち望んでいて、 構成します これらの操作。

プログラムの制御フローを状態マシンに変える機能は、これらの新しいキーワードが興味をそそられるものです。それを考えてください コントロールを生成します, 、値ではなく。

チェックアウト このチャンネル9ビデオ 新しい機能について話しているアンダースの。

ここでの問題は、の署名です ArchiveDocuments 誤解を招きます。それは明示的な返品を持っています void しかし、実際にはリターンです Task. 。私にとってvoidは、それが終了するのを「待つ」方法がないので、同期を意味します。関数の代替署名を考慮してください。

async Task ArchiveDocuments(List<Url> urls) { 
  ...
}

私にとって、それがこのように書かれているとき、違いははるかに明白です。 ArchiveDocuments 機能は、同期して完了するものではなく、後で終了するものです。

通話 FetchAsync() 完了するまでブロックされます(呼び出し内のステートメントがない限り await鍵は、コントロールが発信者に返されることです(なぜなら ArchiveDocuments メソッド自体が宣言されています async)。そのため、発信者はUIロジックの処理を喜んで継続し、イベントに応答します。

いつ FetchAsync() 完了すると、呼び出し元を中断してループを完了します。ヒットします ArchiveAsync() そしてブロック、しかし ArchiveAsync() おそらく、新しいタスクを作成し、開始し、タスクを返します。これにより、タスクが処理されている間に、2番目のループが開始できます。

2番目のループがヒットします FetchAsync() ブロック、コントロールを発信者に戻します。いつ FetchAsync() 完了すると、処理を継続するために呼び出し元を中断します。その後、ヒットします await archive, 、これはコントロールを発信者に戻します Task ループ1で作成された完了。そのタスクが完了すると、発信者が再び中断され、2番目のループが呼び出されます ArchiveAsync(), 、開始タスクを取得し、ループ3を開始し、繰り返します 広告吐き気.

重要なのは、重いリフターが実行されている間に発信者にコントロールを返すことです。

待ち気のキーワードでは、同時性が導入されません。これは、収量キーワードのようなもので、コンパイラに、状態マシンによって制御されたラムダにコードを再構築するように指示します。

待っているコードが「待っている」ことなくどのように見えるかを確認するには、この優れたリンクを参照してください。 http://blogs.msdn.com/b/windowsappdev/archive/2012/04/24/diving-deep-with-winrt-and-await.aspx

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top