My await is awaiting for the heat death of The Universe and beyond
Hello there, so I have method like this:
This is the code from
Program.cs:
Good stuff. And in normal application it works, no problem at all. But I use Terminal.Gui and after Application.Init() it simply don't work.
I heard about this SynchronizationContext stuff and what I've seen Terminal.Gui uses it. I also heard about this .ConfigureAwait(false) But it doesn't work! Application just hangs on this await.
Those two won't worth either:
But then, this one works:
What is going on here? How I can fix it and use juicy async/await with Terminal.Gui? Is it me doing something wrong or just some bug in Terminal.Gui?5 Replies
I'm not sure about this, but you could try:
That shouldn't make any difference whatsoever
Those tasks aren't being awaited
I'm betting that
await blkProvider.ListDevices().ConfigureAwait(false) will work, but I'd want to understand what you're doing that Terminal.Gui doesn't like
It looks like it might install a SynchronizationContext, which posts messages to the main loop which is run by Application.Run?
I don't know how setting up a Terminal.Gui application runs, but I'm guessing you need to be calling Application.Run, and then posting a job to it to do your loading?
I'm guessing by subscribing to either the InitializedChanged or NotifyNewRunState event, then using Application.Run?
Application.MainLoop.Invoke(() => RunInitialization()); before Application.Run might do it too?
Ah yes, Application.Init installs a SynchronizationContext: https://github.com/gui-cs/Terminal.Gui/blob/2be83972036020ce26794a63ad677abf1b54b65f/Terminal.Gui/App/ApplicationImpl.cs#L100
You will not want any awaits before Application.Init, or between Application.Init and Application.RunOh alright, I see. Thanks guys ❤️
though doing it with configure await is fine right
The
ConfigureAwaits you put in place in your sample won't make any difference
You'll need them on every await inside ReadIfExists, and anything which they call, including inside library code. And you might not want to do that, because you might be relying on an await returning a a single-threaded context
Much better to just play along with the threading model that Terminal.Gui wants to use, rather than making sure that every single little bit of your code is correctly configured to side-step it