Mam wielowarstwową aplikację .Net 4,5 wywołującą metodę przy użyciu nowych async
i C #await
słów kluczowych, które po prostu się zawieszają i nie rozumiem, dlaczego.
Na dole mam metodę asynchroniczną, która rozszerza nasze narzędzie bazy danych OurDBConn
(w zasadzie opakowanie dla bazowego DBConnection
i DBCommand
obiektów):
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;
}
Następnie mam metodę asynchroniczną średniego poziomu, która wywołuje to, aby uzyskać wolno działające sumy:
public static async Task<ResultClass> GetTotalAsync( ... )
{
var result = await this.DBConnection.ExecuteAsync<ResultClass>(
ds => ds.Execute("select slow running data into result"));
return result;
}
Wreszcie mam metodę UI (akcję MVC), która działa synchronicznie:
Task<ResultClass> asyncTask = midLevelClass.GetTotalAsync(...);
// do other stuff that takes a few seconds
ResultClass slowTotal = asyncTask.Result;
Problem w tym, że na zawsze wisi na ostatniej linii. Robi to samo, gdy dzwonięasyncTask.Wait()
. Jeśli uruchomię wolną metodę SQL bezpośrednio, zajmie to około 4 sekund.
Spodziewam się zachowania, kiedy to nastąpi asyncTask.Result
, jeśli nie zostanie zakończone, powinno poczekać, aż nastąpi, a gdy to się stanie, powinno zwrócić wynik.
Jeśli przejdę przez debuger, instrukcja SQL kończy się i funkcja lambda kończy się, ale return result;
wierszGetTotalAsync
nie zostanie osiągnięta.
Masz pojęcie, co robię źle?
Jakieś sugestie, gdzie muszę to zbadać, aby to naprawić?
Czy to może być gdzieś impas, a jeśli tak, czy istnieje bezpośredni sposób, aby go znaleźć?
SynchronizationContext
.