4

In MSDN, there is a paragraph like this:

The async and await keywords don't cause additional threads to be created. Async methods don't require multithreading because an async method doesn't run on its own thread. The method runs on the current synchronization context and uses time on the thread only when the method is active. You can use Task.Run to move CPU-bound work to a background thread, but a background thread doesn't help with a process that's just waiting for results to become available.

But it looks I need little more help with the bold text since I am not sure what it exactly means. So how come it becomes async without using Threads?

Source: http://msdn.microsoft.com/en-us/library/hh191443.aspx

4 Answers 4

11

There are many asynchronous operations which don't require the use of multiple threads. Things like Asynchronous IO work by having interrupts which signal when data is available. This allows you to have an asynchronous call which isn't using extra threads - when the signal occurs, the operation completes.

Task.Run can be used to make your own CPU-based async methods, which will run on its own separate thread. The paragraph was intended to show that this isn't the only option, however.

Sign up to request clarification or add additional context in comments.

2 Comments

Could you please visualize such pattern? Lets say I am downloading a file while receiving some input from User. How come I can accomplish such task without using Threads?
There's a pretty good visualization in Lucian Wischik's talk. It's in VB, but the concepts are the same for C#. I also can't resist putting in a plug for my own intro post, which includes important details like the async context and how it's used.
3

async/await is not just about using more threads. It's about using the threads you have more effectively. When operations block, such as waiting on a download or file read, the async/await pattern allows you to use that existing thread for something else. The compiler handles all the magic plumbing underneath, making it much easier to develop with.

See http://msdn.microsoft.com/en-us/magazine/hh456401.aspx for the problem description and the whitepaper at http://www.microsoft.com/en-us/download/details.aspx?id=14058.

Comments

2

Not the code generated by the async and await keyword themselves, no. They create code that runs on your the current thread, assuming it has a synchronization context. If it doesn't then you actually do get threads, but that's using the pattern for no good reason. The await expression, what you write on the right side of the await keyword causes threads to run.

But that thread is often not observable, it may be a device driver thread. Which reports that it is done with a I/O completion port. Pretty common, I/O is always a good reason to use await. If not already forced on you by WinRT, the real reason that async/await got added.

A note about "having a synchronization context". You have one on a thread if the SynchronizationContext.Current property is not null. This is almost only ever the case on the main thread of a gui app. Also the only place where you normally ever worry about having delays not freeze your user interface.

2 Comments

Respectfully disagree, nobugz. A) Async/await are quite useful even when running on thread pool threads (no SyncContext). B) I think async/await would have happened even if WinRT didn't; the world was ready for it. C) SyncContext is heavily used in ASP.NET as well as UI apps.
Hmm, no, we'll have to agree to disagree :)
1

Essentially what it's doing is when you run an async method without calling it with await is this:

  1. Start the method and do as much as possible sychronously.

  2. When necessary, pause the method and put the rest of it into a continuation.

  3. When the async part is completed (is no longer being waited on), schedule the continuation to run on the same thread.

  4. Whatever you want can run on this thread as normal. You can even examine/manipulate the Task returned from the async method.

  5. When the thread becomes available, it will run the rest of your method.

The 'async part' could be file IO, a web request, or pretty much anything, as long as calling code can wait on this task to complete. This includes, but is not limited to, a separate thread. As Reed Copsey pointed out, there are other ways of performing async operations, like interrupts.

1 Comment

The "same thread" is not technically correct. The context is up to the type being awaited; Tasks will - by default - capture and then resume on the current SynchronizationContext, or the current TaskScheduler if there isn't a current SynchronizationContext.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.