I have several async methods that need to synchronize back to the main ui thread.
async Task MyAsyncMethod() {
await DoSomeThingAsync().ConfigureAwait(true);
DoSomethingInTheGui();
}
now i need to call them from a syncronous event handler that is triggered from the gui thread, and the event handler cannot complete until the async method is done. so MyAsyncMethod().Wait()
is not an option, neither is some kind of fire-and-forget solution.
This approach using Nito.AsyncEx seemed promising, but it still deadlocks: https://stackoverflow.com/a/9343733/249456
The only solution i've found seems like a hack to me:
public void RunInGui(Func<Task> action)
{
var window = new Window();
window.Loaded += (sender, args) => action()
.ContinueWith(p => {
window.Dispatcher.Invoke(() =>
{
window.Close();
});
});
window.ShowDialog();
}
Is there a way to get the same effect (block the calling method, allow syncronization back to the gui thread) without creating a new window?
Note: I am aware that refactoring would probably be the best option, but that is a massive undertaking we have to do over longer time. Also worth mentioning that this is a plugin for Autodesk Inventor. The api has several quirks, and all API calls (even non-ui related) have to be executed from the main/ui thread.
Also worth mentioning is that we keep a reference to the main threads dispatcher and use MainThreadDispatcher.InvokeAsync(() => ... )
all around the codebase.