22

私は新しい asyncawaitキーワードについて読んでいて、それは素晴らしいように聞こえますが、これまでに見たどの紹介ビデオでも答えを見つけることができなかった重要な質問が 1 つあります (ホワイトペーパーも読みました)。ちょっと前)。

awaitメイン UI スレッドのネストされた関数で呼び出しがあるとします。この時点でスレッドはどうなりますか?制御はメッセージ ループに戻り、UI スレッドは自由に他の入力を処理できますか?

待機中のタスクが完了すると、スタック全体がメッセージ キューにプッシュされ、ネストされた各関数を介して制御が返されますか?それとも、ここで何か別のことが完全に発生していますか?

第二に (注意を喚起している間)、非同期メソッドに というラベルを付ける必要がある理由がよくわかりませんasync。非同期で実行できるメソッドはありませんか? メソッドを非同期で実行したいが、 async キーワードがない場合はどうすればよいですか? 簡単に実行する方法はありますか?

乾杯。:)

編集: 確かに、サンプルコードをコンパイルできれば、おそらく自分でそれを理解できるでしょうが、何らかの理由でブロックに遭遇しています。私が本当に知りたいのは、継続がどの程度継続するかです...コールスタック全体をフリーズして、タスクが完了したときに再開しますか、それともそれまでに戻るだけですか? 継続をサポートするために、関数自体を非同期としてマークする必要がありますか、それとも (最初に尋ねたように) コール スタック全体を継続しますか?

コール スタック全体がフリーズしない場合、async await が非非同期呼び出し関数にヒットするとどうなりますか? そこでブロックしますか?それはawaitのポイントを打ち負かしませんか?ここで私が理解していないことがわかると思います.誰かが記入してくれることを願っています.

4

2 に答える 2

4

Awaitable の動作に依存します。

同期的に実行するオプションがあります。つまり、スレッドで実行し、同じスレッドの awaiter に制御を返します。

非同期で実行することを選択した場合、awaiter は、awaitable がコールバックをスケジュールしているスレッドでコールバックされます。その間、呼び出し元のスレッドが解放されます。これは、開始された awaitable があるため、非同期作業であり、終了し、awaiter は awaitable のコールバックに接続された継続を持っています。

2 番目の質問については、async キーワードは、メソッドが非同期的に呼び出されるかどうかではなく、そのメソッドの本体が非同期コードをインラインで呼び出すかどうかに関するものです。

つまり、Task または Task を返すメソッドは非同期で (awaited または continuewith で) 呼び出すことができますが、async でマークすることにより、そのメソッドは本体で await キーワードを使用できるようになり、返されたときに Task は返されませんが、本体全体が、タスクが実行するステート マシンに書き換えられるため、単に T です。

メソッドがあるとしましょう

public async Task DoSomething() {
}

UI スレッドから呼び出すと、タスクが返されます。この時点で、TaskScheduler で非同期メソッドを実行する、.Wait()またはそれを実行する Task をブロックするか、UI スレッドでそれを実行するブロックを使用できます。もちろん、内部で発生する待機は基本的に別の継続であるため、TaskScheduler スレッドでコードの一部を実行することになる可能性があります。ただし、通常の同期メソッドと同様に、最終的に UI スレッドは完了するまでブロックされます。.Result.RunSynchronously()DoSomething

.ContinueWith()または、タスクの完了時に TaskScheduler によって呼び出されるアクションを作成する継続をスケジュールすることもできます。これにより、UI スレッドで行っていたことを引き続き実行する現在のコードに制御が戻ります。継続はコールスタックをキャプチャしません。これは単なるアクションであるため、外部スコープからアクセスする変数をキャプチャするだけです。

于 2011-08-11T20:26:46.900 に答える