最速の学習のために...
メソッドの実行フローを理解する(図付き):3分
この画像では、#6にのみ焦点を当てます(これ以上はありません)
#6ステップ:実行が不足したため、ここで実行が停止しました。続行するには、getStringTask(関数の種類)からの結果が必要です。したがって、await
オペレーターを使用して進行を一時停止し、(このメソッドの)呼び出し元に制御を戻します(yield)。getStringTaskの実際の呼び出しは、#2の前半で行われました。#2では、文字列の結果を返すことが約束されました。しかし、いつ結果が返されますか?私たちは(#1:AccessTheWebAsync)2回目の呼び出しをもう一度行う必要がありますか?#2(ステートメントを呼び出す)または#6(ステートメントを待つ)結果を誰が取得するか
AccessTheWebAsync()の外部呼び出し元も待機しています。したがって、呼び出し元はAccessTheWebAsyncを待機しており、AccessTheWebAsyncは現時点でGetStringAsyncを待機しています。興味深いのは、AccessTheWebAsyncが待機する前にいくつかの作業を行ったことです(#4)。マルチタスクへの同じ自由は、外部の呼び出し元(およびチェーン内のすべての呼び出し元)にも利用でき、これはこの「非同期」の最大の利点です!あなたはそれが同期しているように感じます..または通常ですが、そうではありません。
メソッドがすでに返されていることを思い出してください(#2)。再度返すことはできません(2回目は不可)。では、発信者はどのように知るのでしょうか?それはすべてタスクに関するものです!タスクが渡されました。タスクは待機されました(メソッドではなく、値ではありません)。タスクに値が設定されます。タスクのステータスは完了に設定されます。呼び出し元はタスク(#6)を監視するだけです。したがって、6#は、結果をどこで、誰が取得するかに対する答えです。後でここでさらに読む。
酒を学ぶための質問内省:1分
質問を少し調整してみましょう:
いつどのように使用しますか? async
await
Tasks
学習Task
は他の2つを自動的にカバーします(そしてあなたの質問に答えます)
シンタックスシュガーをすばやく理解する:5分
変換前(独自の方法)
internal static int Method(int arg0, int arg1)
{
int result = arg0 + arg1;
IO(); // Do some long running IO.
return result;
}
上記のメソッドを呼び出すタスク化されたメソッド
internal static Task<int> MethodTask(int arg0, int arg1)
{
Task<int> task = new Task<int>(() => Method(arg0, arg1));
task.Start(); // Hot task (started task) should always be returned.
return task;
}
待機または非同期について言及しましたか?いいえ。上記のメソッドを呼び出すと、監視可能なタスクが取得されます。タスクが何を返すかはすでにわかっています。整数です。
タスクの呼び出しは少し注意が必要です。そのとき、キーワードが表示され始めます。MethodTask()を呼び出しましょう
internal static async Task<int> MethodAsync(int arg0, int arg1)
{
int result = await HelperMethods.MethodTask(arg0, arg1);
return result;
}
上記の同じコードが下の画像として追加されました:
- タスクが完了するのを「待っています」。従って
await
- awaitを使用するため、使用する必要があります
async
(必須構文)
Async
接頭辞としてのMethodAsync (コーディング標準)
await
理解するのは簡単ですが、残りの2つ(async
、Async
)は:)ではない場合があります。まあ、それはコンパイラにとってもっと理にかなっているはずです。
したがって、2つの部分があります。
- 「タスク」を作成する
- タスクを呼び出す構文糖を作成する(
await+async
)
AccessTheWebAsync()への外部の呼び出し元があり、その呼び出し元も惜しまないことを思い出してください。つまり、同じことが必要await+async
です。そしてチェーンは続きます。しかし、常にTask
一方の端があります。
大丈夫ですが、1人の開発者は#1(タスク)が見つからないことに驚きました...
開発者の混乱を共有する:5分
開発者が実装しないことを間違えましたTask
が、それでも動作します!質問と、ここに記載されている回答のみを理解してください。あなたが読んで完全に理解したことを願っています。要約すると、「タスク」は表示または実装されない可能性がありますが、親クラスのどこかに実装されています。同様に、私たちの例では、すでにビルドされたものを呼び出すMethodAsync()
方が、自分でTask
(MethodTask()
)を使用してそのメソッドを実装するよりもはるかに簡単です。ほとんどの開発者はTasks
、コードを非同期コードに変換するときに頭を動かすのが難しいと感じています。
ヒント:既存の非同期実装(MethodAsync
またはなどToListAsync
)を見つけて、問題を外部委託してください。したがって、Asyncとawaitを処理するだけで済みます(これは簡単で、通常のコードとかなり類似しています)。
問題:通常のコードの実際の実装を非同期操作にすばやく変更:2分
以下に示すデータレイヤーのコード行が壊れ始めました(多くの場所)。一部のコードを.Net framework 4.2。*から.Net coreに更新したためです。アプリケーション全体で1時間でこれを修正する必要がありました。
var myContract = query.Where(c => c.ContractID == _contractID).First();
簡単!
- QueryableExtensionsがあるため、EntityFramework nugetパッケージをインストールしました。換言すれば、それは、私たちはシンプルで非同期実装(タスク)生き残ることができない
Async
とawait
のコードで。
- 名前空間= Microsoft.EntityFrameworkCore
呼び出しコード行はこのように変更されました
var myContract = await query.Where(c => c.ContractID == _contractID).FirstAsync();
メソッドの署名が変更されました
Contract GetContract(int contractnumber)
に
async Task<Contract> GetContractAsync(int contractnumber)
呼び出しメソッドも影響を受けました:GetContractAsync(123456);
として呼び出されましたGetContractAsync(123456).Result;
30分で随時交換!
しかし、建築家は、このためだけにEntityFrameworkライブラリを使用しないように私たちに言いました!おっとっと!ドラマ!次に、カスタムタスク実装(yuk)を作成しました。あなたはその方法を知っています。まだ簡単です!..まだまだゆく..
次はどこ?ASP.Net Coreでの同期呼び出しの非同期への変換
について見ることができる素晴らしい簡単なビデオがあります。おそらく、これを読んだ後に進む方向でしょう。