Ich habe mehrere asynchrone Methoden, die zurück zum Haupt-ui-Thread synchronisiert werden müssen.Wie blockiere ich eine Methode, während eine asynchrone Methode ausgeführt wird, ohne dass es zu Deadlocks im UI-Thread kommt
async Task MyAsyncMethod() {
await DoSomeThingAsync().ConfigureAwait(true);
DoSomethingInTheGui();
}
jetzt brauche ich sie von einem syncronous Ereignisbehandlungsroutine aufzurufen, die von der GUI-Thread ausgelöst wird, und der Event-Handler kann nicht abgeschlossen werden, bis die Asynchron-Methode durchgeführt wird. So ist MyAsyncMethod().Wait()
keine Option, auch keine Art von Feuer-und-Vergessen-Lösung.
Dieser Ansatz Nito.AsyncEx vielversprechend schien, aber es immer noch Deadlocks: https://stackoverflow.com/a/9343733/249456
Die einzige Lösung, die ich mir scheint wie ein Hack gefunden habe:
public void RunInGui(Func<Task> action)
{
var window = new Window();
window.Loaded += (sender, args) => action()
.ContinueWith(p => {
window.Dispatcher.Invoke(() =>
{
window.Close();
});
});
window.ShowDialog();
}
Gibt es einen Weg, um der gleiche Effekt (Blockieren Sie die aufrufende Methode, erlauben Sie die Synchronisierung auf den GUI-Thread), ohne ein neues Fenster zu erstellen?
Hinweis: Mir ist bewusst, dass Refactoring wahrscheinlich die beste Option wäre, aber das ist eine massive Aufgabe, die wir über längere Zeit erledigen müssen. Erwähnenswert ist auch, dass dies ein Plugin für Autodesk Inventor ist. Die API hat mehrere Macken, und alle API-Aufrufe (auch nicht-ui-bezogen) müssen vom Haupt/ui-Thread ausgeführt werden.
Auch erwähnenswert ist, dass wir einen Verweis auf den Hauptthreads Dispatcher behalten und MainThreadDispatcher.InvokeAsync(() => ...)
rund um die Codebasis verwenden.
Sie müssen Ihren UIhread nicht blockieren. Solange Sie eine Anforderung haben, Ihren UInthread zu blockieren (insbesondere während andere Prozesse tatsächlich den UInthread verwenden müssen), befinden Sie sich in einer Welt voller Verletzungen. Entfernen Sie diese Anforderung, wenn Sie Wert auf Ihre Gesundheit legen. – Servy
* Warum * einen synchronen Event-Handler verwenden? Warum nicht ein * asynchroner & Event-Handler? ZB async void Button_Click (..) {awary MyAsyncMethod1(); away MyAsyncMethod2();} ' –
Eine weitere Option ist die Verwendung von Progress, um Nachrichten zurück an den UI-Thread zu senden. Die Nutzlast eines Progress muss keine Zeichenfolge oder eine Fortschrittsnachricht sein, es kann sich um ein beliebiges Objekt handeln. Aktivieren Sie [Async in 4.5: Aktivieren von Fortschritt und Abbruch in Async-APIs] (https://blogs.msdn.microsoft.com/dotnet/2012/06/06/asyncin-4-5-enabling-progress-and-cancellation -in-async-apis /) –