このコードでは:
public async Task v_task()
{
await Task.Run(() => Console.WriteLine("Hello!"));
}
public async void v1()
{
await v_task();
// some other actions...
}
public void ButtonClick()
{
v1();
Console.WriteLine("Hi!");
}
ButtonClickが呼び出された場合、非同期/待機によって生成された下位スレッドプールで実際に並行して実行される上記のメソッドはどれですか?
つまり、async / awaitで動作する競合状態についての私の懸念は何ですか?すべての非同期メソッドは、同じ呼び出し元のスレッドで必須に実行されますか?可能な共有状態でミューテックスを使用する必要がありますか?はいの場合、共有状態オブジェクトをどのように検出できますか?
ButtonClickが呼び出された場合、非同期/待機によって生成された下位スレッドプールで実際に並行して実行される上記のメソッドはどれですか?
Console.WriteLine
内のみTask.Run
。
つまり、async / awaitで動作する競合状態についての私の懸念は何ですか?
実際にどのように機能するかを説明している私のasync
イントロを読むことから始めることをお勧めしますawait
。
要約すると、async
メソッドは通常、シリアル非同期方式で記述されます。このコードを例にとってみましょう。
CodeBeforeAwait();
await SomeOtherMethodAsync();
CodeAfterAwait();
CodeBeforeAwait
それSomeOtherMethodAsync
は最初に完了まで実行され、次に呼び出されるといつでも言うことができます。次に、メソッドは(非同期で)SomeOtherMethodAsync
完了するのを待ち、その後でのみCodeAfterAwait
呼び出されます。
したがって、シリアル非同期です。期待どおりにシリアルに実行されますが、そのフロー内の非同期ポイント(await
)でも実行されます。
さて、あなたはすることができないと言うCodeBeforeAwait
と、CodeAfterAwait
多くの文脈がないわけではない、少なくとも、同じスレッド内で実行されます。await
デフォルトでは、現在SynchronizationContext
(またはTaskScheduler
SyncCtxがない場合は現在)で再開します。上記のサンプルメソッドはUIスレッドで実行されたのであれば、あなたがいることを知っているだろうCodeBeforeAwait
とCodeAfterAwait
UIスレッドで実行されます両方。ただし、コンテキストなしで(つまり、バックグラウンドスレッドまたはコンソールメインスレッドから)CodeAfterAwait
実行された場合は、別のスレッドで実行される可能性があります。
メソッドの一部が別のスレッドで実行されている場合でも、ランタイムはメソッドを続行する前にバリアを配置するので、変数アクセスをバリアする必要がないことに注意してください。
また、元の例ではTask.Run
、スレッドプールに作業を明示的に配置するを使用していることに注意してください。これはasync
/とはかなり異なり、await
マルチスレッドとして扱う必要があります。
可能な共有状態でミューテックスを使用する必要がありますか?
はい。たとえば、コードでがを使用している場合はTask.Run
、それを別のスレッドとして扱う必要があります。(注していることawait
、それはだ多くの他のスレッドとすべてではない共有状態に簡単に-あなたは純粋なあなたのバックグラウンドタスクを保つことができれば、彼らはとの仕事に非常に簡単です)。
はいの場合、共有状態オブジェクトをどのように検出できますか?
他の種類のマルチスレッドコードと同じ答え:コード検査。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加