2

新しい async キーワードと await キーワードは、計算を行うためにスレッドを追加する必要がある GUI アプリケーションで有用であり、新しいキーワードを使用すると非常に簡単になります。しかし、他のタイプのアプリケーションはどうでしょうか?

たとえば、何らかの作業を行うサーバーや、常にデータを処理するプロセスですか? 私がまだ新しいキーワードを誤解しているのかもしれませんが、これらのタイプのアプリケーションは新しいキーワードの恩恵を受けますか?それともより明示的なマルチスレッドのためにタスクを使い続けるべきでしょうか?

4

5 に答える 5

2

非 GUI アプリケーションで を使用する主な利点は、awaitI/O を行っているときです。

「古い方法」で行っている場合は、I/O に同期メソッドを使用し、スレッドが動作している間はスレッドをブロックします。を使用するawaitと、スレッドをブロックしません。つまり、アプリケーションが使用するスレッドが少なくなり、メモリ使用量が大幅に減少し (各スレッドに 1 MB のメモリが必要)、全体的なパフォーマンスが向上します。

古い非同期プログラミング モデルを使用して同様の改善を実現できますが、はるかに面倒です。

非 GUI アプリケーションが必要以上に多くのスレッドを使用することを気にしない場合は、 をあまり使用する必要はありませawaitん。しかし、あなたがそれを気にするなら、awaitあなたを大いに助けることができます.

于 2012-08-14T22:30:49.283 に答える
1

awaitタスクを補完asyncします。

引き続きタスクを使用する必要がありますが、タスクawaitと一緒に and を使用すると、非同期メソッドasyncの記述が簡単になります。

于 2012-08-14T20:13:48.100 に答える
1

たとえば、何らかの作業を行うサーバーや、常にデータを処理するプロセスですか?

これはここで非常に適切です。たとえば、WCF サービスでは、async と await を使用して、ブロックせずに複数の非同期サービス リクエストを 1 つの非同期リクエストにまとめることができます。

私がまだ新しいキーワードを誤解しているのかもしれませんが、これらのタイプのアプリケーションは新しいキーワードの恩恵を受けますか?それとも、より明示的なマルチスレッドのためにタスクを使用し続ける必要がありますか?

2人はうまく連携しています。Async と await を使用すると、多くの場合、 と を使用する複数の操作の操作と構成がTaskはるかTask<T>に簡単になります。

ただし、「最低レベル」では、actual を作成するコードはTask、同じ TPL ベースの手法を使用してそうする可能性があります。Task、 async 、および await を作成するメソッドを取得したら、そのメソッドを使用して作成します (それを使用してより多くの非同期メソッドを作成するか、それを使用して複数のタスクを同時に実行するメソッドを作成することを含む)、はるかに簡単になります。

于 2012-08-14T20:17:10.673 に答える
1

最終的にブロックせずに非同期で実行され、コールバック メソッドがあるメソッドを呼び出す予定がある場合はいつでも、新しいキーワードを使用してその構文を簡単にすることができます。コールバック コードがなく、継続渡しスタイルのプログラミングに従っていない場合、新しいキーワードはおそらく役に立ちません。(これは、本当に…本当に使いたいのであれば、それらを使用できないと言っているわけではありません。)

于 2012-08-14T20:17:19.533 に答える
0

たとえば、何らかの作業を行うサーバーや、常にデータを処理するプロセスですか? 私がまだ新しいキーワードを誤解しているのかもしれませんが、これらのタイプのアプリケーションは新しいキーワードの恩恵を受けますか?それとも、より明示的なマルチスレッドのためにタスクを使用し続ける必要がありますか?

数か月前に初めて TAP を使い始めたとき、私はこの同じ質問に取り組み、TAP は同時実行の「サーバーのような」シナリオで非常にうまく機能し、より重要なシナリオに「ドロップダウン」する必要がないという結論に達しました。 TPLのエリアなど

たとえば、私が現在取り組んでいるアプリケーション (これは GUI アプリであり、余談ですが、GUI スレッドを解放するために TAP も使用しています) は、SSH を使用してかなり多数の外部マシンと繰り返し通信する必要があります。アプリが a) 各外部マシンに「コマンド」ファイルを送信する必要がある大きなループを想像してみてください。b) しばらくしてから、すべての外部マシンに「進行状況」ファイルをポーリングします (つまり、SSH を使用してファイルのダウンロードを試みます)。 、c)しばらくして、これらすべてのマシンをポーリングして「完了」ファイルなどを探します。これらの手順は、「完了」するまで何度も繰り返されます。

このアプリの最初の作成では、このすべての SSH i/o が同期的に実行され、各ステップを実行する累積時間が長すぎました。さらに多くの外部マシンをサポートするようにアプリに依頼したため、うまくスケーリングできなかったことは言うまでもありません。

それ以来、このアプリケーションを書き直して、これらの各ステップ (上記の a、b、c) を同時に実行できるようにしました。したがって、たとえば、すべての外部マシンへのコマンド ファイルの送信は、次々にではなくほぼ同時に行われるため、アプリはこれらのステップ (a、b、c) 間をより迅速に移動できます。外部マシンを追加すると、劣化が少なくなります。

私が使用しているSSHライブラリはそれ自体で「非同期」機能を提供しないため(ただし、ライブラリはスレッドセーフです)、Task.Run()を介して各ssh操作を開始し、「await Task. WhenAll(タスクリスト)'. 完了したら、各タスクを調べて結果を確認し、それに応じて処理を進めます。

TAP を使用してコード内でこれをすべて非常にわかりやすく、見やすくするだけでなく、キャンセルと進行状況オブジェクトのサポートを使用して、キャンセルを処理し、これらのアクティビティの進行状況をユーザーに報告しています。

これまでのところ、これは素晴らしく機能しており、TPL などにこれよりも「深く」入る必要はありませんでした。一部の人々は、「重度の並行性」を得ると、TPL に深く入り込む必要があるかもしれないと述べましたが、私は個人的にはまだ「なぜ」を見たことがありません..

したがって、アプリケーションの「タイプ」(GUI、サーバーなど) に基づいて TAP の有用性を判断するのではなく、アプリで実行する必要があるアクティビティの性質によって決定すると言えます。複数の計算を同時に実行する必要がある場合は、TAP が最適です。同時に実行する必要がある I/O が多数ある場合は、TAP が最適です。また、TAP を使用して GUI スレッドを解放する典型的な例を知っています。

于 2012-08-28T15:54:00.867 に答える