Je suis dans le processus de mise à jour d'une bibliothèque qui a une API de surface qui a été construit en .NET 3.5. En conséquence, toutes les méthodes sont synchrones. Je ne peux pas changer l'API (c'est à dire, de convertir les valeurs de retour à la Tâche) parce que cela exigerait que tous les appelants changement. Donc, je suis parti avec à la meilleure manière d'appel de méthodes asynchrones en mode synchrone. C'est dans le contexte de ASP.NET 4, ASP.NET de Base, et .NET/.NET de Base des applications console.
Je ne peut pas avoir été assez clair sur la situation, c'est que j'ai un code existant qui n'est pas asynchrone au courant, et je veux utiliser les nouvelles bibliothèques comme Système.Net.Http et le kit SDK AWS qui prennent en charge uniquement de méthodes asynchrones. J'ai donc besoin de combler l'écart, et être en mesure d'avoir un code qui peut être appelée de manière synchrone mais alors peut-appel de méthodes asynchrones ailleurs.
J'ai fait beaucoup de lecture, et il y a un certain nombre de fois ce qui a été demandé et répondu.
L'appel de méthode asynchrone de non méthode async
L'appel d'une méthode asynchrone à partir d'une méthode synchrone
Comment puis-je exécuter un async Task<T> méthode synchrone?
L'appel de méthode asynchrone synchrone
Comment appeler la méthode asynchrone synchrone de méthode en C#?
Le problème est que la plupart des réponses sont différentes! L'approche la plus commune que j'ai vu est utiliser .Le résultat, mais cela peut impasse. J'ai essayé tous les suivants, et qu'ils travaillent, mais je ne suis pas sûr de ce qui est la meilleure approche pour éviter les blocages, ont de bonnes performances, et joue bien avec le moteur d'exécution (en termes d'honorer la tâche des planificateurs, des tâches des options de création, etc). Est-il une réponse définitive? Quelle est la meilleure approche?
private static T taskSyncRunner<T>(Func<Task<T>> task)
{
T result;
// approach 1
result = Task.Run(async () => await task()).ConfigureAwait(false).GetAwaiter().GetResult();
// approach 2
result = Task.Run(task).ConfigureAwait(false).GetAwaiter().GetResult();
// approach 3
result = task().ConfigureAwait(false).GetAwaiter().GetResult();
// approach 4
result = Task.Run(task).Result;
// approach 5
result = Task.Run(task).GetAwaiter().GetResult();
// approach 6
var t = task();
t.RunSynchronously();
result = t.Result;
// approach 7
var t1 = task();
Task.WaitAll(t1);
result = t1.Result;
// approach 8?
return result;
}