ホームページ >バックエンド開発 >C++ >タスクの結果にアクセスすると非同期 C# メソッドがハングするのはなぜですか?

タスクの結果にアクセスすると非同期 C# メソッドがハングするのはなぜですか?

Barbara Streisand
Barbara Streisandオリジナル
2025-01-08 13:47:42951ブラウズ

Why Does My Asynchronous C# Method Hang When Accessing Task Results?

タスクの結果にアクセスするときに C# 非同期メソッドがハングする理由

非同期プログラミングに C# の async および await キーワードを使用する場合、特定の構造によって予期しない動作やデッドロックが発生する可能性があります。

次のシナリオを考えてみましょう。多層アプリケーションは、SQL クエリを非同期に実行して結果を返す拡張データベース ユーティリティ メソッド ExecuteAsync を使用します。中間層メソッド GetTotalAsyncExecuteAsync を呼び出してデータを取得し、結果を asyncTask 変数に保存します。最後に、UI 操作は asyncTask.Result を使用して結果に同期的にアクセスしようとします。ただし、アプリケーションは無期限にハングします。

デッドロックの原因

問題は、GetTotalAsync メソッドで await を使用することで発生します。デフォルトでは、非同期メソッドの継続は、メソッドを開始したのと同じ SynchronizationContext でディスパッチされます。この場合、UI スレッドで await を使用すると、継続 (return result;) も UI スレッドで実行されるようにスケジュールされます。

asyncTask.Result が UI スレッドで呼び出されると、タスクの完了時にスレッドがブロックされます。ただし、UI スレッドでスケジュールされた継続は、asyncTask.Result が完了するまで実行できません。これにより、どちらのスレッドも実行を続行できないデッドロックが発生します。

解決策

このデッドロックを解決するには、いくつかの方法があります:

1. 非同期キーワードを削除します:

await の使用を削除し、ExecuteAsync メソッドと GetTotalAsync メソッドを待機しない純粋な非同期メソッドとして書き直します。

<code class="language-csharp">public static Task<T> ExecuteAsync<T>(this OurDBConn dataSource, Func<OurDBConn, T> function)
{
    // ... (代码保持不变)
}

public static Task<ResultClass> GetTotalAsync(...)
{
    // ... (代码保持不变)
}</code>

2. ConfigureAwait を使用します:

ConfigureAwait(false) を使用して、UI スレッドで継続をスケジュールしないように指定します:

<code class="language-csharp">public static async Task<ResultClass> GetTotalAsync(...)
{
    var resultTask = this.DBConnection.ExecuteAsync<ResultClass>(
        ds => ds.Execute("select slow running data into result"));

    return await resultTask.ConfigureAwait(false);
}</code>

このアプローチでは、すべての await 操作で ConfigureAwait(false) を明示的に指定する必要があり、デッドロックが発生する可能性があることに注意してください。

3. SynchronizationContext を使用します:

非同期操作用に特定の SynchronizationContext を作成し、すべての await 操作でそのコンテキストが使用されるようにして、UI スレッドとの競合を防ぎます。

以上がタスクの結果にアクセスすると非同期 C# メソッドがハングするのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。