1

async-await機能により、ノンブロッキングコードの記述がエレガントになります。ただし、非ブロッキングではありますが、非同期関数内で実行される作業は重要です。

非同期コードを書くとき、いわば「うさぎの穴のずっと下まで」のパターンに従うコードを書くのが自然だと思います。ここで、呼び出しツリー内のすべてのメソッドは非同期とマークされ、使用されるAPIは非同期です。ただし、ブロックされていない場合でも、実行されたコードはコンテキストスレッドのかなりの時間を費やす可能性があります。

非同期に加えて非同期可能なメソッドを同時に実行することをいつどのように決定しますか?新しいタスクをコールツリーの上位または下位に作成することに誤りがありますか?このタイプの「最適化」のベストプラクティスはありますか?

4

2 に答える 2

6

私はasync数年間生産で使用してきました。私が推奨するコアとなる「ベスト プラクティス」がいくつかあります。

  1. asyncコードでブロックしないでくださいasync「ずっと」を使います。(結果:を使用する必要ない限り、を使用することasync Taskをお勧めします)。async voidasync void
  2. ConfigureAwait(false)「ライブラリ」メソッドで可能な限り使用してください。

あなたはすでに「asyncずっと下まで」の部分を理解しており、ConfigureAwait(false)役に立つポイントに来ています。

別のasyncメソッドAを呼び出すasyncメソッドがあるとしますBAの結果で UI を更新しますが、UI にBB依存しません。したがって、次のようになります。

async Task A()
{
  var result = await B();
  myUIElement.Text = result;
}

async Task<string> B()
{
  var rawString = await SomeOtherStuff();
  var result = DoProcessingOnRawString(rawString);
  return result;
}

この例でBは、UI コンテキストで実際に実行する必要がないため、「ライブラリ」メソッドを呼び出します。現在、UI スレッドで実行されているためB DoProcessingOnRawString応答性の問題が発生しています。

したがって、ConfigureAwait(false)すべての in に a をawait追加しBます。

async Task<string> B()
{
  var rawString = await SomeOtherStuff().ConfigureAwait(false);
  var result = DoProcessingOnRawString(rawString);
  return result;
}

これで、 がingB後に再開すると(実際に する必要があると仮定して)、UI コンテキストではなくスレッド プール スレッドで再開されます。完了すると、スレッド プールで実行されていても、UI コンテキストで再開されます。awaitSomeOtherStuffawaitBA

UI コンテキストに依存ConfigureAwait(false)するAため、追加できません。A

また、タスクを明示的にスレッド プールにキューイングするオプションもあり ( await Task.Run(..))、特定の CPU 集中型機能がある場合は、これを行う必要があります。しかし、パフォーマンスが「何千ものペーパー カット」に苦しんでいる場合は、 を使用して、多くの「ハウスキーピング」をスレッド プールConfigureAwait(false)にオフロードできます。async

私のイントロ ポストが役に立つかもしれません(「理由」の詳細が説明されています)。また、asyncFAQにも多くの優れたリファレンスがあります。

于 2012-09-18T18:44:25.317 に答える
0

Async-awaitは、現在の.NETプロセススペースのスレッドを実際には使用しません。これは、データベース呼び出し、Web要求、一部のファイルIOなどのIOおよびネットワーク操作を「ブロック」するように設計されています。

あなたがウサギの穴のテクニックと呼んでいるものに対して、C#にどのような利点があるのか​​私にはわかりません。そうすることは、コードを曖昧にするだけであり、潜在的に高いCPUコードをIOコードに不必要に結合します。

あなたの質問に直接答えるために、私は前述のIO /ネットワークシナリオに対してのみ非同期待機を使用します。ブロッキング操作を実行している時点で、 CPUにバインドされているものについては、スレッド化手法を使用して最大限に活用します。利用可能なCPUコアの。2つの懸念を混ぜ合わせる必要はありません。

于 2012-09-18T18:06:55.713 に答える