J'ai une application .Net 4.5 multi-niveaux qui appelle une méthode utilisant le nouvel outil C# async
y await
des mots-clés qui se bloquent et je ne vois pas pourquoi.
En bas, j'ai une méthode asynchrone qui étend notre utilitaire de base de données. OurDBConn
(il s'agit essentiellement d'une enveloppe pour le système sous-jacent DBConnection
y DBCommand
objets) :
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;
}
Ensuite, j'ai une méthode asynchrone de niveau intermédiaire qui appelle cette méthode pour obtenir des totaux lents :
public static async Task<ResultClass> GetTotalAsync( ... )
{
var result = await this.DBConnection.ExecuteAsync<ResultClass>(
ds => ds.Execute("select slow running data into result"));
return result;
}
Enfin, j'ai une méthode UI (une action MVC) qui s'exécute de manière synchrone :
Task<ResultClass> asyncTask = midLevelClass.GetTotalAsync(...);
// do other stuff that takes a few seconds
ResultClass slowTotal = asyncTask.Result;
Le problème est qu'il s'accroche à cette dernière ligne pour toujours. Il fait la même chose si j'appelle asyncTask.Wait()
. Si j'exécute directement la méthode SQL lente, cela prend environ 4 secondes.
Le comportement que j'attends est que lorsqu'il arrive à asyncTask.Result
si elle n'est pas terminée, elle doit attendre qu'elle le soit, et une fois qu'elle l'est, elle doit renvoyer le résultat.
Si j'interviens avec un débogueur, l'instruction SQL se termine et la fonction lambda se termine, mais la fonction return result;
ligne de GetTotalAsync
n'est jamais atteint.
Une idée de ce que je fais mal ?
Avez-vous des suggestions sur la façon dont je dois enquêter pour résoudre ce problème ?
Pourrait-il s'agir d'un blocage quelque part, et si oui, existe-t-il un moyen direct de le trouver ?