私はC#の新しい使用法呼び出すマルチティアの.Net 4.5アプリケーション持つasync
とawait
そのキーワードだけでハングアップし、私はなぜ見ることができません。
一番下には、データベースユーティリティを拡張する非同期メソッドがありますOurDBConn
(基本的には、基になるオブジェクトDBConnection
とDBCommand
オブジェクトのラッパー)。
public static async Task<T> ExecuteAsync<T>(this OurDBConn dataSource, Func<OurDBConn, T> function)
{
string connectionString = dataSource.ConnectionString;
// Start the SQL and pass back to the caller until finished
T result = await Task.Run(
() =>
{
// Copy the SQL connection so that we don't get two commands running at the same time on the same open connection
using (var ds = new OurDBConn(connectionString))
{
return function(ds);
}
});
return result;
}
次に、これを呼び出して遅い合計を取得する中レベルの非同期メソッドがあります:
public static async Task<ResultClass> GetTotalAsync( ... )
{
var result = await this.DBConnection.ExecuteAsync<ResultClass>(
ds => ds.Execute("select slow running data into result"));
return result;
}
最後に、同期的に実行されるUIメソッド(MVCアクション)があります。
Task<ResultClass> asyncTask = midLevelClass.GetTotalAsync(...);
// do other stuff that takes a few seconds
ResultClass slowTotal = asyncTask.Result;
問題は、それがその最後の行に永遠に掛かることです。呼び出しても同じことですasyncTask.Wait()
。遅いSQLメソッドを直接実行すると、約4秒かかります。
私が期待している振る舞いは、に到達したときにasyncTask.Result
、終了していない場合は終了するまで待機し、終了したら結果を返すことです。
デバッガーでステップスルーすると、SQLステートメントは完了し、ラムダ関数は終了しますが、return result;
行にGetTotalAsync
到達しません。
私が間違っていることは何か考えていますか?
これを修正するために調査する必要がある場所への提案はありますか?
これはどこかでデッドロックになる可能性がありますか?そうであれば、それを見つける直接的な方法はありますか?
SynchronizationContext
です。