Ich habe eine mehrschichtige .NET 4.5-Anwendung, die eine Methode mit C #s neuem async
und aufruftawait
Schlüsselwörtern , die nur hängt, und ich kann nicht verstehen, warum.
Unten habe ich eine asynchrone Methode, die unser Datenbankdienstprogramm erweitert OurDBConn
(im Grunde ein Wrapper für den Basiswert DBConnection
und die DBCommand
Objekte):
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;
}
Dann habe ich eine asynchrone Methode der mittleren Ebene, die dies aufruft, um einige langsam laufende Summen zu erhalten:
public static async Task<ResultClass> GetTotalAsync( ... )
{
var result = await this.DBConnection.ExecuteAsync<ResultClass>(
ds => ds.Execute("select slow running data into result"));
return result;
}
Endlich habe ich eine UI-Methode (eine MVC-Aktion), die synchron ausgeführt wird:
Task<ResultClass> asyncTask = midLevelClass.GetTotalAsync(...);
// do other stuff that takes a few seconds
ResultClass slowTotal = asyncTask.Result;
Das Problem ist, dass es für immer in dieser letzten Zeile hängt. Es macht das gleiche, wenn ich anrufeasyncTask.Wait()
. Wenn ich die langsame SQL-Methode direkt ausführe, dauert es ungefähr 4 Sekunden.
Das Verhalten, das ich erwarte, ist das, wenn es darum geht asyncTask.Result
fertig ist, wenn es nicht fertig ist, es warten sollte, bis es ist, und sobald es ist, sollte es das Ergebnis zurückgeben.
Wenn ich mit einem Debugger durchkomme, wird die SQL-Anweisung abgeschlossen und die Lambda-Funktion beendet, aber die return result;
Zeile vonGetTotalAsync
wird nie erreicht.
Irgendeine Idee, was ich falsch mache?
Irgendwelche Vorschläge, wo ich nachforschen muss, um dies zu beheben?
Könnte dies irgendwo ein Deadlock sein, und wenn ja, gibt es einen direkten Weg, ihn zu finden?
SynchronizationContext
.