[解決済み] Task.ConfigureAwait(continueOnCapturedContext: false)をわざわざ使う必要があるのか?
疑問点
次のようなウィンドウズフォームのコードを考えてみましょう。
private async void UpdateUIControlClicked(object sender, EventArgs e)
{
this.txtUIControl.Text = "I will be updated after await - i hope!";
await Task.Delay(5000).ConfigureAwait(continueOnCapturedContext: false);
this.txtUIControl.Text = "I am updated now.";
}
ここでは、3行目で例外が発生しています。これは、awaitの後に、UIでないスレッドでコードが実行されているためです。 ConfigureAwait(false)はどこで役に立つのでしょうか?
どのように解決するのですか?
Stephen Cleary は、この件に関して非常に優れたシリーズを持っており、ここで見ることができます。
Stephen Cleary はこのシリーズをとてもよく読んでいます。たいていの場合、あなたは は必要ありません。 に同期する必要はありません。ほとんどの非同期メソッドは、合成を念頭に置いて設計されているでしょう。それらは他の操作を待ち、それぞれが非同期操作そのものを表します(他の操作によって合成することができます)。この場合、awaiter に次のように指示します。 ではなく を呼び出すことで、現在のコンテキストをキャプチャします。 構成待ち を呼び出し
false
を、例えばprivate async Task DownloadFileAsync(string fileName) { // Use HttpClient or whatever to download the file contents. var fileContents = await DownloadFileContentsAsync(fileName).ConfigureAwait(false); // Note that because of the ConfigureAwait(false), we are not on the original context here. // Instead, we're running on the thread pool. // Write the file contents out to a disk file. await WriteToDiskAsync(fileName, fileContents).ConfigureAwait(false); // The second call to ConfigureAwait(false) is not *required*, but it is Good Practice. } // WinForms example (it works exactly the same for WPF). private async void DownloadFileButton_Click(object sender, EventArgs e) { // Since we asynchronously wait, the UI thread is not blocked by the file download. await DownloadFileAsync(fileNameTextBox.Text); // Since we resume on the UI context, we can directly access UI elements. resultTextBox.Text = "File downloaded!"; }
この例で注意すべき重要な点は、非同期メソッド呼び出しの各「レベル」が独自のコンテキストを持っているということです。
DownloadFileButton_Click
は UI コンテキストで開始しDownloadFileAsync
.DownloadFileAsync
も UI コンテキストで開始されましたが、その後にConfigureAwait(false)
. 残りのDownloadFileAsync
はスレッドプールコンテキストで実行される。しかしDownloadFileAsync
が完了しDownloadFileButton
_Click が再開されると を行います。 UI コンテキストで再開します。良い経験則は
ConfigureAwait(false)
ただし する はコンテキストが必要です。
関連
-
[解決済み】ASP.NET Core Dependency Injectionのエラーです。アクティブ化しようとしているときに、タイプのサービスを解決できません。
-
[解決済み】C#のequal to演算子でtextとvarcharのデータ型は互換性がない
-
[解決済み] 2つのリストを結合する
-
[解決済み】2年前のMSDateを把握する【クローズド
-
[解決済み】URLから画像をダウンロードする方法
-
[解決済み】名前 'ViewBag' が現在のコンテキストに存在しない - Visual Studio 2015
-
[解決済み] IDisposable インターフェースの正しい使用法
-
[解決済み] EqualsメソッドがオーバーライドされたときにGetHashCodeをオーバーライドすることが重要な理由は何ですか?
-
[解決済み] async」と「await」の使い方とタイミング
-
[解決済み】なぜFunc<T>ではなくExpression<Func<T>を使うのですか?
最新
-
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 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】Excel "外部テーブルが期待された形式ではありません。"
-
[解決済み】SmtpException: トランスポート接続からデータを読み取れません:net_io_connectionclosed
-
[解決済み】Unity3DでOnTriggerEnterが動作しない件
-
[解決済み] [Solved] 不正な文字列値: '\xEFxBFxBD' for column
-
[解決済み】MetadataException: 指定されたメタデータ・リソースをロードできない
-
[解決済み】値をNULLにすることはできません。パラメータ名:source
-
[解決済み] ...基礎となる接続は閉じられました。予期しないエラーが受信で発生しました
-
[解決済み】Unityでゲームオブジェクトのすべての子をループスルーして破壊する方法?
-
[解決済み] すべてのサーバーサイドのコードでConfigureAwaitを呼び出すためのベストプラクティス
-
[解決済み] Task.Runの正しい使い方とasync-awaitだけの使い方