[解決済み] すべてのサーバーサイドのコードでConfigureAwaitを呼び出すためのベストプラクティス
質問
サーバーサイドのコード(例えば、いくつかの
ApiController
を返すような非同期な関数を作成した場合、その関数は
Task<SomeObject>
- を呼び出すことは、ベストプラクティスと考えられています。
ConfigureAwait(false)
?
スレッドコンテキストの切り替えを元のスレッドコンテキストに戻す必要がないので、よりパフォーマンスが高いと読んだことがあります。 しかし、ASP.NET Web Apiでは、リクエストが1つのスレッドで受信され、何らかの関数を待機させながら
ConfigureAwait(false)
の最終結果を返すときに、別のスレッドに移動してしまう可能性があります。
ApiController
関数を使用します。
以下に、その例をタイプしてみました。
public class CustomerController : ApiController
{
public async Task<Customer> Get(int id)
{
// you are on a particular thread here
var customer = await GetCustomerAsync(id).ConfigureAwait(false);
// now you are on a different thread! will that cause problems?
return customer;
}
}
解決方法は?
更新してください。
ASP.NET Coreには
SynchronizationContext
. ASP.NET Coreであれば、以下のようにしても問題ありません。
ConfigureAwait(false)
を使用するかどうか。
ASP.NET "Full"や"Classic"などの場合、この回答の残りの部分はそのまま適用されます。
元の投稿(非コアASP.NET用)。
ASP.NETチームによるこのビデオには、「Space」、「Space」、「Space」の使用に関する最良の情報が含まれています。
async
をASP.NET上で使用することができます。
スレッドコンテキストを元のスレッドコンテキストに戻す必要がないため、よりパフォーマンスが高いと読んだことがあります。
これは、UI アプリケーションで、quot;sync" に戻らなければならない UI スレッドが 1 つだけである場合に当てはまります。
ASP.NETの場合、状況はもう少し複雑です。ASP.NETの場合
async
メソッドの実行が再開されると、ASP.NET のスレッドプールからスレッドを取得します。を使用してコンテキスト・キャプチャを無効化すると
ConfigureAwait(false)
この場合、スレッドはメソッドを直接実行し続けるだけです。コンテキストキャプチャを無効にしない場合、スレッドはリクエストコンテキストに再入力し、メソッドの実行を継続します。
そこで
ConfigureAwait(false)
リクエストコンテキストを再入力する手間が省けますが、これは通常非常に高速です。
ConfigureAwait(false)
かもしれない
は、リクエストに対して少量の並列処理を行おうとする場合に便利ですが、実際には、そのようなシナリオのほとんどにTPLがより適しています。
しかし、ASP.NET Web Apiでは、リクエストが1つのスレッドで受信され、何らかの関数を待ち、ConfigureAwait(false)を呼び出すと、ApiController関数の最終結果を返すときに別のスレッドに置かれる可能性があるのです。
実は
await
はそれができる。一度、あなたの
async
メソッドが
await
は、その
メソッド
はブロックされますが
スレッド
はスレッドプールに戻る。メソッドを続行する準備ができたら、スレッドプールから任意のスレッドを取り出し、メソッドを再開するために使用されます。
唯一の違いは
ConfigureAwait
ASP.NETでは、メソッドを再開するときに、そのスレッドがリクエストコンテキストに入るかどうかです。
背景については、私の
に関するMSDN記事
SynchronizationContext
と私の
async
イントロブログ記事
.
関連
-
[解決済み】Excel "外部テーブルが期待された形式ではありません。"
-
[解決済み】Sequence contains no matching element(シーケンスにマッチする要素がない
-
[解決済み】Unity3DでOnTriggerEnterが動作しない件
-
[解決済み】C# - パスに不正な文字がある場合
-
[解決済み】Unity 「関連するスクリプトを読み込むことができません」「Win32Exception: システムは指定されたファイルを見つけることができません"
-
[解決済み】値をNULLにすることはできません。パラメータ名:source
-
[解決済み】「namespace」なのに「type」のように使われる。
-
[解決済み] ASP.NET Web APIでエラーを返すためのベストプラクティス
-
[解決済み] C#でawaitを使わずに非同期メソッドを安全に呼び出す方法
-
[解決済み】非同期プログラミングとマルチスレッドの違いは何ですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】ここで「要求URIに一致するHTTPリソースが見つかりませんでした」となるのはなぜですか?
-
[解決済み】ソケットのアドレス(プロトコル/ネットワークアドレス/ポート)は、通常1つしか使用できない?
-
[解決済み】プロジェクトビルド時のエラー。エディタでスクリプトにコンパイルエラーがあるため、Playerのビルドにエラーが発生する
-
[解決済み】バックスラッシュを含むパス文字列のエスケープシーケンスが認識されない件
-
[解決済み】"指定されたパスのフォーマットはサポートされていません。"
-
[解決済み】5.7.57 SMTP - MAIL FROMエラー時に匿名メールを送信するためにクライアントが認証されない
-
[解決済み】ファイルへの読み書きの際に共有違反のIOExceptionが発生する C#
-
[解決済み】ファイルやアセンブリ、またはその依存関係の1つをロードできませんでした。
-
[解決済み】Nullableオブジェクトは値を持たなければならない?
-
[解決済み] await vs Task.Wait - デッドロック?