Let's say I have a method fooCPU
that runs synchronously (it doesn't call pure async methods performing I/O, or use other threads to run its code by calling Task.Run
or similar ways). That method performs some heavy calculations - it's CPU bound.
Now I call fooCPU
in my program without delegating it to be executed by a worker thread. If one line of fooCPU
will take long to run, no other lines will be executed until it finishes. So for example, calling it from the UI thread causes the UI thread to freeze (GUI will become unresponsive).
When I stated that async/await
is an imitation of mutlithreading. The lines of two different pieces of code are executed in turns, on a single thread. If one of these lines will take long to run, no other lines will be executed until it finishes.,
I've been told that it's true for async used on the UI thread, but it's not true for all other cases (ASP.NET, async on the thread pool, console apps, etc).
Could anyone tell me what this might mean? How is UI thread different from the main thread of a console program?
I think nobody wants anyone here on this forum to continue the discussion of related topics, as they appear in the comments for instance, so it's better to ask a new question.
I recommend you read my async
intro post; it explains how the async
and await
keywords work. Then, if you're interested in writing asynchronous code, continue with my async
best practices article.
The relevant parts of the intro post:
The beginning of an async method is executed just like any other method. That is, it runs synchronously until it hits an “await” (or throws an exception).
So this is why the inner method in your console code example (without an await
) was running synchronously.
Await examines that awaitable to see if it has already completed; if the awaitable has already completed, then the method just continues running (synchronously, just like a regular method).
So this is why the outer method in your console code example (that was await
ing the inner method which was synchronous) was running synchronously.
Later on, when the awaitable completes, it will execute the remainder of the async method. If you’re awaiting a built-in awaitable (such as a task), then the remainder of the async method will execute on a “context” that was captured before the “await” returned.
This "context" is SynchronizationContext.Current
unless it is null
, in which case it is TaskScheduler.Current
. Or, the simpler version:
What exactly is that “context”? Simple answer:
- If you’re on a UI thread, then it’s a UI context.
- If you’re responding to an ASP.NET request, then it’s an ASP.NET request context.
- Otherwise, it’s usually a thread pool context.
Putting all of this together, you can visualize async
/await
as working like this: the method is split into several "chunks", with each await
acting as a point where the method is split. The first chunk is always run synchronously, and at each split point it may continue either synchronously or asynchronously. If it continues asynchronously, then it will continue in a captured context (by default). UI threads provide a context that will execute the next chunk on the UI thread.
So, to answer this question, the special thing about UI threads is that they provide a SynchronizationContext
that queues work back to that same UI thread.
I think nobody wants anyone here on this forum to continue the discussion of related topics, as they appear in the comments for instance, so it's better to ask a new question.
Well, Stack Overflow is specifically not intended to be a forum; it's a Question & Answer site. So it's not a place to ask for exhaustive tutorials; it's a place to come when you're stuck trying to get code working or if you don't understand something after having researched everything you can about it. This is why the comments on SO are (purposefully) restricted - they have to be short, no nice code formatting, etc. Comments on this site are intended for clarification, not as a discussion or forum thread.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With