Tôi có một ứng dụng .Net 4.5 nhiều tầng gọi một phương thức bằng C # mới của async
await
từ khóa và chỉ bị treo và tôi không thể hiểu tại sao.
Ở phía dưới, tôi có một phương thức không đồng bộ mở rộng tiện ích cơ sở dữ liệu của chúng tôi OurDBConn
(về cơ bản là một trình bao bọc cho cơ sở DBConnection
và DBCommand
các đối tượng):
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;
}
Sau đó, tôi có một phương thức không đồng bộ mức độ trung bình gọi điều này để nhận một số tổng số chạy chậm:
public static async Task<ResultClass> GetTotalAsync( ... )
{
var result = await this.DBConnection.ExecuteAsync<ResultClass>(
ds => ds.Execute("select slow running data into result"));
return result;
}
Cuối cùng, tôi có một phương thức giao diện người dùng (một hành động MVC) chạy đồng bộ:
Task<ResultClass> asyncTask = midLevelClass.GetTotalAsync(...);
// do other stuff that takes a few seconds
ResultClass slowTotal = asyncTask.Result;
Vấn đề là nó bị treo ở dòng cuối cùng đó mãi mãi. Nó làm điều tương tự nếu tôi gọi asyncTask.Wait()
. Nếu tôi chạy trực tiếp phương pháp SQL chậm thì mất khoảng 4 giây.
Hành vi mà tôi mong đợi là khi nó đến asyncTask.Result
, nếu nó chưa kết thúc, nó nên đợi cho đến khi nó đạt được, và khi nó đã xong nó sẽ trả về kết quả.
Nếu tôi bước qua với trình gỡ lỗi, câu lệnh SQL hoàn thành và hàm lambda kết thúc, nhưng return result;
dòng của GetTotalAsync
không bao giờ đạt được.
Bất kỳ ý tưởng những gì tôi đang làm sai?
Bất kỳ đề xuất nào về nơi tôi cần điều tra để khắc phục điều này?
Đây có thể là một điểm bế tắc ở đâu đó, và nếu có thì có cách nào trực tiếp để tìm ra nó không?
SynchronizationContext
.