I’m making an OpenGL game using a custom graphics library. I’ve been thinking about using async-await for an easier UI, but I’m not sure how to get this done.


The main thread is the one that raises events such as mouse move/click or keyboard typing. UI Elements can have their own events based on these, so for example a Button has an event Clicked which would therefore also get called in the main thread.
Those events could start a Task, but since the rest of the game is not async (it’s often suggested to go “async all the way”, but it would be foolish to do so in this case) the question is, where do these tasks run? (like, in which thread?)
If said task needs to do something long (such as attempting to connect to a server), I can use TaskCompletionSource to make a task that waits for the server response and set it to completed (this all happens in the main thread). But once the task is completed, where does it resume?
Do I need to do some special configuration to the TPL to do stuff like this? I’ve only used async-await with Xamarin before so I don’t have deep knowledge on how it works.
Thanks!
When you await a task, the continuation of the method after the task is complete is up to the current SynchronizationContext (unless ConfigureAwait(false) is used).
The default SynchronizationContext queues the continuation on the thread pool, so it can run on arbitrary threads and multiple continuations can run simultaneously. Various GUI frameworks have their own SynchronizationContext implementations, e.g. WinForms sends a window message to itself so the continuations will be processed by the application’s message loop like any other UI event.
You can implement and set your own SynchronizationContext, a reasonably simple implementation could put the delegates in a ConcurrentQueue<T> and then you dequeue and call the delegates in your main loop somewhere.
This is what I was looking for!
I thought about a case where when a button is pressed, I start a task that awaits Task.Delay(5000) and then do something on the main thread.
After the delay, the task would probably be on another thread. So I was thinking about making a queue of Action<T>s and something like a ExecuteOnMainThreadAsync(Action<T>) to queue ’em up.
But since the UI will mainly be simple stuff, there’s no reason to have things being executed on separate threads, so making my own SynchronizationContext is definitely a better idea.
You probably don’t want to await Task that’s meant to be asynchronous.
async/await is just syntactic sugar for making a continuation look like synchronous code.
Is equivalent to something like:
The first looks synchronous, i.e. value + 1 depends on the result of the task, so you still need to wait for Task.Run to complete, and to avoid writing the second, .NET whips up a state machine for you. This is the main reason to use asymc/await.
If your code is working fine with starting Tasks up and letting them run asynchronously, then you should be good to go.
As mentioned by others Tasks are executed on separate threads. Once a task it completed, the thread is returned to the ThreadPool. You only ContinueWth if you have to do something after it returns, and you certainly should not await a task that is asynchronous.
Hello, rupertavery: code blocks using backticks (“`) don’t work on all versions of Reddit!
Some users see this / this instead.


To fix this, indent every line with 4 spaces instead. It’s a bit annoying, but then your code blocks are properly formatted for everyone.
An easy way to do this is to use the code-block button in the editor. If it’s not working, try switching to the fancy-pants editor and back again.
Comment with formatting fixed for old.reddit.com users
FAQ
You can opt out by replying with backtickopt6 to this comment.
C# devs
null reference exceptions

source