Saya memiliki aplikasi multi-tier .Net 4.5 yang memanggil metode menggunakan kata kunci baru C # async
dan await
yang baru saja hang dan saya tidak dapat melihat alasannya.
Di bagian bawah saya memiliki metode async yang memperluas utilitas database kami OurDBConn
(pada dasarnya pembungkus untuk objek DBConnection
dan yang mendasarinya 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;
}
Lalu saya memiliki metode asinkron tingkat menengah yang memanggil ini untuk mendapatkan beberapa total yang berjalan lambat:
public static async Task<ResultClass> GetTotalAsync( ... )
{
var result = await this.DBConnection.ExecuteAsync<ResultClass>(
ds => ds.Execute("select slow running data into result"));
return result;
}
Akhirnya saya memiliki metode UI (tindakan MVC) yang berjalan secara sinkron:
Task<ResultClass> asyncTask = midLevelClass.GetTotalAsync(...);
// do other stuff that takes a few seconds
ResultClass slowTotal = asyncTask.Result;
Masalahnya adalah itu tergantung pada baris terakhir itu selamanya. Itu melakukan hal yang sama jika saya menelepon asyncTask.Wait()
. Jika saya menjalankan metode SQL lambat secara langsung dibutuhkan sekitar 4 detik.
Perilaku yang saya harapkan adalah ketika sampai asyncTask.Result
, jika belum selesai harus menunggu sampai selesai, dan setelah itu akan mengembalikan hasilnya.
Jika saya melangkah melalui debugger, pernyataan SQL selesai dan fungsi lambda selesai, tetapi return result;
baris GetTotalAsync
tidak pernah tercapai.
Tahu apa yang saya lakukan salah?
Adakah saran di mana saya perlu menyelidiki untuk memperbaikinya?
Mungkinkah ini menjadi jalan buntu di suatu tempat, dan jika demikian apakah ada cara langsung untuk menemukannya?
SynchronizationContext
.