Karl Stephen
Karl Stephen

Reputation: 1140

Is async/await pattern irrelevant without threading or asynchronous devices?

Edit - After reading the three answers below, I've realized that I'm asking nonsense ! Apologies for wasting some of your precious time, and thanks for clarifying alot of misunderstandings, really! :)

I were assuming apples and pipe wrenches were the same thing in the way async/await and threads are solution for similar concerns. Async/await and Threads both addresses UI responsiveness, but not in the same way. The former is a pattern to be used when several desired results can be gathered asynchronously (in order to improve user experience for example), hence why it's called "async". Heavy works, those that take several seconds to hours has to be off loaded on another thread to keep UI responsive. Those two are completely different concerns.

No matter how I may edit this question, there is no way to ask such async/await with or without threading concern as they are completely different things, can be used together (in so many ways) or separately. The statement .2 below said it all (apart a "invocation" misconception) but I didn't truely understood its true meaning from the start.

I guess I should have deleted the question from the moment I had doubts, but I couldn't understand how far it was a dumb one before actually reading some answers. However, this may also help other to have a better understanding of what async/await is about.

By the way, I don't know what answer to mark as answer as they all have valuable informations.


Original post:

It's fair to note that I'm "yet another async/await beginner". However, What I've understood so far are:

  1. async/await doesn't create threads ! Never ! They run on the same thread as the caller.
  2. async/await are not parallel tasks. They just defines a pattern where an async block of code get executed the moment an await is invoked at caller level (or so - I know my understanding is slightly wrong, but that's how I can clearly picture it in mind)
  3. No code block is executed asynchronuously if that block doesn't contain an await keyword.
  4. async/await appears to work well with some I/O tasks, but seems not that wonderful on most high CPU computations.
  5. async/await seems to fail with Thread.Sleep (should use Task.Delay instead) or in case of Exception with Finally block.

Based on the above, and to simplify things, I think async/await is just an improved form of goto, capable of jumping from a method step to another method step, because the goto call can "fly" (be delayed) until an await is encountered ! (sorry to simplify things that far)

I've tested both I/O and CPU codes without additional threads, both heavy, and both produced unresponsive UI until everything was completed.

My observaton is:

Without asynchronous capable things like :

async/await are just plain synchronous patterns; meaning, there is no asynchronous-like thing anywhere with just async/await keywords.

The question is: is the above observation true, or am I missing some important thing about async/await ?


Side notes :

I've read this blog post (There Is No Thread, Stephen Cleary's Blog). He states that there is no thread (totally agree) but it doesn't contradict with my observation that, at pure programmer code level without asynchronous devices involved, you can't have a responsive UI unless you delegate the heavy tasks in another thread. My concern is not the awaitable aspect of the pattern, as I said, it's like a flying goto; I want to make sure I'm not using async/await blindly just for the sake of using something new.

.ConfigureAwait(false) : seems to involve a ThreadPool to me, which is why the UI thread is still responsive...

Upvotes: 3

Views: 1768

Answers (3)

i3arnon
i3arnon

Reputation: 116548

Async-await is a pattern that allows you to write code that closely resembles synchronous code but can actually execute asynchronously. This relies on a lot of work done by the compiler. That's all.

Async-await doesn't create asynchronous operations, it just allows you to use them in a simple way and still be asynchronous, unlike before using BeginXXX/EndXXX.

It's true that async is mostly useful with I/O, because most asynchronous operations are I/O operations, but there are different ones like Task.Delay, asynchronous synchronization mechanisms or asynchronously waiting for an event.

About your specific points:

  1. Async-await doesn't create threads. Async methods start running on the caller thread, don't use any thread for the actual asynchronous operation and resume on a ThreadPool thread or one defined by the SynchronizationContext or TaskScheduler.
  2. Await isn't invoked. When an async method reaches an await on an uncompleted task the rest of the method is scheduled as a continuation that will run when that task is completed.
  3. Pretty much. You need to await an asynchronous operation for your async method to be asynchronous.
  4. Async-await works with both. If your operation isn't asynchronous though, there's no point in using async-await.
  5. Async-await doesn't fail with Thread.Sleep. It's just wasteful to use Thread.Sleep as it blocks a thread. That's why you use Task.Delay. You can now await in finally with C# 6.

And finally:

meaning, there is no asynchronous-like thing anywhere with just async/await keywords.

Yes, marking a method with the async keyword doesn't make anything run asynchronously. It only allows you to use await and wrap the result in a Task.

Upvotes: 4

Stephen Cleary
Stephen Cleary

Reputation: 456497

You may find my async intro helpful.

I would say that async and await are the most elegant way to consume asynchronous operations. As a side product, async also creates a higher-level asynchronous operation (if the method returns a Task/Task<T>). However, they are not a good way for creating asynchronous operations out of nothing.

So I would disagree with this statement:

async/await are just plain synchronous patterns

However, I would agree with the statement that await just breaks up an async method into multiple synchronous parts.

If you have CPU-bound code and you don't want to block the UI thread, then you could use something like Task.Run to push that code onto a thread pool thread. The UI code can then await the task returned from Task.Run.

Upvotes: 4

Venemo
Venemo

Reputation: 19067

There are two distinct concepts here that you are mixing up. Being asynchronous and parallel are not the same thing. While asynchronous operations can hide multithreading under the hood, they don't necessarily do.

The async / await keywords in C# are just syntactic sugar for expressing thoughts like “when operation A is done, do operation B”. Whether or not operation A runs on another thread is an implementation detail you don't care about.

Basically, you let the compiler and the framework figure it out for you.

If you think of it, async / await can be conceptionally somewhat similar to how events and event loops work. Perhaps the event syntax was not flexible enough and that's why they introduced these new keywords. Personally I believe that it's kind of in the same legaue as promises in JavaScript or how the event loop works in Node.js. I'm not saying that it works similarly but it does solve very similar problems.

Upvotes: 2

Related Questions