Ich bin dabei, eine Bibliothek mit einer API-Oberfläche zu aktualisieren, die in .NET 3.5 erstellt wurde. Infolgedessen sind alle Methoden synchron. Ich kann die API nicht ändern (dh Rückgabewerte in Task konvertieren), da dies die Änderung aller Aufrufer erfordern würde. Ich habe also die Möglichkeit, asynchrone Methoden am besten synchron aufzurufen. Dies steht im Zusammenhang mit ASP.NET 4-, ASP.NET Core- und .NET / .NET Core-Konsolenanwendungen.
Ich war möglicherweise nicht klar genug - die Situation ist, dass ich vorhandenen Code habe, der nicht asynchron ist, und ich möchte neue Bibliotheken wie System.Net.Http und das AWS SDK verwenden, die nur asynchrone Methoden unterstützen. Ich muss also die Lücke schließen und in der Lage sein, Code zu haben, der synchron aufgerufen werden kann, aber dann an anderer Stelle asynchrone Methoden aufrufen kann.
Ich habe viel gelesen und es wurde mehrmals gefragt und beantwortet.
Aufrufen der asynchronen Methode von der nicht asynchronen Methode
Synchrones Warten auf eine asynchrone Operation und warum friert Wait () das Programm hier ein
Aufrufen einer asynchronen Methode von einer synchronen Methode
Wie würde ich eine asynchrone Task <T> -Methode synchron ausführen?
Asynchrone Methode synchron aufrufen
Wie rufe ich eine asynchrone Methode von einer synchronen Methode in C # auf?
Das Problem ist, dass die meisten Antworten unterschiedlich sind! Der häufigste Ansatz, den ich gesehen habe, ist die Verwendung von .Result, aber dies kann zum Stillstand kommen. Ich habe alles Folgende ausprobiert und sie funktionieren, aber ich bin mir nicht sicher, welcher Ansatz der beste ist, um Deadlocks zu vermeiden, eine gute Leistung zu erzielen und gut mit der Laufzeit zu spielen (in Bezug auf die Einhaltung von Aufgabenplanern, Optionen zur Aufgabenerstellung usw.) ). Gibt es eine endgültige Antwort? Was ist der beste Ansatz?
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;
}