By Dan Dinu

2013-01-22 09:29:58 8 Comments

From my understanding one of the main things that async and await do is to make code easy to write and read - but is using them equal to spawning background threads to perform long duration logic?

I'm currently trying out the most basic example. I've added some comments inline. Can you clarify it for me?

// I don't understand why this method must be marked as `async`.
private async void button1_Click(object sender, EventArgs e)
    Task<int> access = DoSomethingAsync();
    // task independent stuff here

    // this line is reached after the 5 seconds sleep from 
    // DoSomethingAsync() method. Shouldn't it be reached immediately? 
    int a = 1; 

    // from my understanding the waiting should be done here.
    int x = await access; 

async Task<int> DoSomethingAsync()
    // is this executed on a background thread?
    return 1;


@Stephen Cleary 2013-01-22 13:17:40

From my understanding one of the main things that async and await do is to make code easy to write and read.

They're to make asynchronous code easy to write and read, yes.

Is it the same thing as spawning background threads to perform long duration logic?

Not at all.

// I don't understand why this method must be marked as 'async'.

The async keyword enables the await keyword. So any method using await must be marked async.

// This line is reached after the 5 seconds sleep from DoSomethingAsync() method. Shouldn't it be reached immediately?

No, because async methods are not run on another thread by default.

// Is this executed on a background thread?


You may find my async/await intro helpful. The official MSDN docs are also unusually good (particularly the TAP section), and the async team put out an excellent FAQ.

@Roman Plášil 2013-08-18 16:59:29

So it's not running on a background thread, but it also doesn't block. This is possible due to asynchronous API's which use callbacks instead of juggling with threads. You initiate an (I/O, socket, ..) operation and return to doing your things. When the operation is done, the OS will invoke the callback. This is what Node.js or the Python Twisted framework does and they have some nice explanation, too.

@Stanislav 2014-01-14 15:07:07

"The async keyword enables the await keyword. So any method using await must be marked async.", - but why? this answer doesn't help to understand why the method must be marked as async. Can't the compiler just infer that the method is async by looking inside for await keywords?

@Stephen Cleary 2014-01-14 16:25:26

@Stanislav: I have a blog entry that addresses that question.

@DavidRR 2016-05-27 19:11:53

Suggested clarification: No, because async methods are not run on another thread by default. In your example, the Sleep() call within DoSomethingAsync() blocks the current thread which prevents execution from continuing within button1_Click() until DoSomethingAsync() completes. Note that while Thread.Sleep() blocks the executing thread, Task.Delay() does not.

@Hakim 2018-09-27 17:28:26

Async / Await

Actually Async / Await are a pair of keywords which are just syntactic sugar for creating a callback of an asynchronous task.

Take by example this operation:

    public static void DoSomeWork()
        var task = Task.Run(() =>
            // [RUNS ON WORKER THREAD]

            // IS NOT bubbling up due to the different threads
            throw new Exception();

            return "Hello";

        // This is the callback
        task.ContinueWith((t) => {
            // -> Exception is swallowed silently

            // [RUNS ON WORKER THREAD]

The code above has several disadvantages. Errors are not passed on and it's hard to read. But Async and Await come in to help us out:

    public async static void DoSomeWork()
        var result = await Task.Run(() =>
            // [RUNS ON WORKER THREAD]

            // IS bubbling up
            throw new Exception();

            return "Hello";

        // every thing below is a callback 
        // (including the calling methods)



Await calls have to be in Async methods. This has some advantages:

  • Returns the result of the Task
  • creates automatically a callback
  • checks for errors and lets them bubble up in callstack (only up to none-await calls in callstack)
  • waits for the result
  • frees up the main thread
  • runs the callback on the main thread
  • uses a worker thread from the threadpool for the task
  • makes the code easy to read
  • and a lot more

NOTE: Async and Await are used with asynchronous calls not to make these. You have to use Task Libary for this, like Task.Run() .

Here is a comparison between await and none await solutions

This is the none async solution:

    public static long DoTask()

        // [RUNS ON MAIN THREAD]
        var task = Task.Run(() => {
            // [RUNS ON WORKER THREAD]
        // goes directly further
        // WITHOUT waiting until the task is finished

        // [RUNS ON MAIN THREAD]

        // 50 milliseconds
        return stopWatch.ElapsedMilliseconds;

This is the async method:

    public async static Task<long> DoAwaitTask()

        // [RUNS ON MAIN THREAD]

        await Task.Run(() => {
            // [RUNS ON WORKER THREAD]
        // Waits until task is finished

        // [RUNS ON MAIN THREAD]

        // 2050 milliseconds
        return stopWatch.ElapsedMilliseconds;

You can actually call an async method without the await keyword but this means that any Exception here are swallowed in release mode:

    public static Stopwatch stopWatch { get; } = new Stopwatch();

    static void Main(string[] args)
        Console.WriteLine("DoAwaitTask: " + DoAwaitTask().Result + " ms");
        // 2050 (2000 more because of the await)
        Console.WriteLine("DoTask: " + DoTask() + " ms");
        // 50

Async and Await are not meant for parallel computing. They are used to not block your main thread. When it's about or Windows applications, blocking your main thread due to a network call is a bad thing. If you do this, your app will get unresponsive or even crash.

Check out ms docs for more examples.

@KSib 2019-03-12 13:56:46

This seems wrong. On the "none" async solution it would pause for 1 second as the thread sleep would run on the main thread.

@James Mallon 2019-01-25 12:24:22

Async & Await Simple Explanation

Simple Analogy

A person may wait for their morning train. This is all they are doing as this is their primary task that they are currently performing. (synchronous programming (what you normally do!))

Another person may await their morning train whilst they smoke a cigarette and then drink their coffee. (Asynchronous programming)

What is asynchronous programming?

Asynchronous programming is where a programmer will choose to run some of his code on a separate thread from the main thread of execution and then notify the main thread on it's completion.

What does the async keyword actually do?

Prefixing the async keyword to a method name like

async void DoSomething(){ . . .

allows the programmer to use the await keyword when calling asynchronous tasks. That's all it does.

Why is this important?

In a lot of software systems the main thread is reserved for operations specifically relating to the User Interface. If I am running a very complex recursive algorithm that takes 5 seconds to complete on my computer, but I am running this on the Main Thread (UI thread) When the user tries to click on anything on my application, it will appear to be frozen as my main thread has queued and is currently processing far too many operations. As a result the main thread cannot process the mouse click to run the method from the button click.

When do you use Async and Await?

Use the asynchronous keywords ideally when you are doing anything that doesn't involve the user interface.

So lets say you're writing a program that allows the user to sketch on their mobile phone but every 5 seconds it is going to be checking the weather on the internet.

We should be awaiting the call the polling calls every 5 seconds to the network to get the weather as the user of the application needs to keep interacting with the mobile touch screen to draw pretty pictures.

How do you use Async and Await

Following on from the example above, here is some pseudo code of how to write it:

    //this is called every 5 seconds
    async void CheckWeather()
        var weather = await GetWeather();
        //do something with the weather now you have it

    async Task<WeatherResult> GetWeather()

        var weatherJson = await CallToNetworkAddressToGetWeather();
        return deserializeJson<weatherJson>(weatherJson);

    //This method is called whenever the screen is pressed
    void ScreenPressed()

@Prashant 2019-11-27 09:44:19

Thanks for taking time to write this one.

@Zaheer Abbas 2018-04-26 10:51:54

Below is code which reads excel file by opening dialog and then uses async and wait to run asynchronous the code which reads one by one line from excel and binds to grid

namespace EmailBillingRates
    public partial class Form1 : Form
        public Form1()
            lblProcessing.Text = "";

        private async void btnReadExcel_Click(object sender, EventArgs e)
            string filename = OpenFileDialog();

            Microsoft.Office.Interop.Excel.Application xlApp = new Microsoft.Office.Interop.Excel.Application();
            Microsoft.Office.Interop.Excel.Workbook xlWorkbook = xlApp.Workbooks.Open(filename);
            Microsoft.Office.Interop.Excel._Worksheet xlWorksheet = xlWorkbook.Sheets[1];
            Microsoft.Office.Interop.Excel.Range xlRange = xlWorksheet.UsedRange;
                Task<int> longRunningTask = BindGrid(xlRange);
                int result = await longRunningTask;

            catch (Exception ex)
               // GC.Collect();

                //rule of thumb for releasing com objects:  
                //  never use two dots, all COM objects must be referenced and released individually  
                //  ex: [somthing].[something].[something] is bad  

                //release com objects to fully kill excel process from running in the background  

                //close and release  

                //quit and release  


        private void btnSendEmail_Click(object sender, EventArgs e)


        private string OpenFileDialog()
            string filename = "";
            OpenFileDialog fdlg = new OpenFileDialog();
            fdlg.Title = "Excel File Dialog";
            fdlg.InitialDirectory = @"c:\";
            fdlg.Filter = "All files (*.*)|*.*|All files (*.*)|*.*";
            fdlg.FilterIndex = 2;
            fdlg.RestoreDirectory = true;
            if (fdlg.ShowDialog() == DialogResult.OK)
                filename = fdlg.FileName;
            return filename;

        private async Task<int> BindGrid(Microsoft.Office.Interop.Excel.Range xlRange)
            lblProcessing.Text = "Processing File.. Please wait";
            int rowCount = xlRange.Rows.Count;
            int colCount = xlRange.Columns.Count;

            // dt.Column = colCount;  
            dataGridView1.ColumnCount = colCount;
            dataGridView1.RowCount = rowCount;

            for (int i = 1; i <= rowCount; i++)
                for (int j = 1; j <= colCount; j++)
                    //write the value to the Grid  
                    if (xlRange.Cells[i, j] != null && xlRange.Cells[i, j].Value2 != null)
                         await Task.Delay(1);
                         dataGridView1.Rows[i - 1].Cells[j - 1].Value =  xlRange.Cells[i, j].Value2.ToString();

            lblProcessing.Text = "";
            return 0;

    internal class async

@Joe Phillips 2017-05-26 14:55:26


Here is a quick example of async/await at a high level. There are a lot more details to consider beyond this.

Note: Task.Delay(1000) simulates doing work for 1 second. I think it's best to think of this as waiting for a response from an external resource. Since our code is waiting for a response, the system can set the running task off to the side and come back to it once it's finished. Meanwhile, it can do some other work on that thread.

In the example below, the first block is doing exactly that. It starts all the tasks immediately (the Task.Delay lines) and sets them off to the side. The code will pause on the await a line until the 1 second delay is done before going to the next line. Since b, c, d, and e all started executing at almost the exact same time as a (due to lack of the await), they should finish at roughly the same time in this case.

In the example below, the second block is starting a task and waiting for it to finish (that is what await does) before starting the subsequent tasks. Each iteration of this takes 1 second. The await is pausing the program and waiting for the result before continuing. This is the main difference between the first and second blocks.



// This block takes 1 second to run because all
// 5 tasks are running simultaneously
    var a = Task.Delay(1000);
    var b = Task.Delay(1000);
    var c = Task.Delay(1000);
    var d = Task.Delay(1000);
    var e = Task.Delay(1000);

    await a;
    await b;
    await c;
    await d;
    await e;


// This block takes 5 seconds to run because each "await"
// pauses the code until the task finishes
    await Task.Delay(1000);
    await Task.Delay(1000);
    await Task.Delay(1000);
    await Task.Delay(1000);
    await Task.Delay(1000);


5/24/2017 2:22:50 PM
5/24/2017 2:22:51 PM (First block took 1 second)
5/24/2017 2:22:56 PM (Second block took 5 seconds)

Extra info regarding SynchronizationContext

Note: This is where things get a little foggy for me, so if I'm wrong on anything, please correct me and I will update the answer. It's important to have a basic understanding of how this works but you can get by without being an expert on it as long as you never use ConfigureAwait(false), although you will likely lose out on some opportunity for optimization, I assume.

There is one aspect of this which makes the async/await concept somewhat trickier to grasp. That's the fact that in this example, this is all happening on the same thread (or at least what appears to be the same thread in regards to its SynchronizationContext). By default, await will restore the synchronization context of the original thread that it was running on. For example, in ASP.NET you have an HttpContext which is tied to a thread when a request comes in. This context contains things specific to the original Http request such as the original Request object which has things like language, IP address, headers, etc. If you switch threads halfway through processing something, you could potentially end up trying to pull information out of this object on a different HttpContext which could be disastrous. If you know you won't be using the context for anything, you can choose to "not care" about it. This basically allows your code to run on a separate thread without bringing the context around with it.

How do you achieve this? By default, the await a; code actually is making an assumption that you DO want to capture and restore the context:

await a; //Same as the line below
await a.ConfigureAwait(true);

If you want to allow the main code to continue on a new thread without the original context, you simply use false instead of true so it knows it doesn't need to restore the context.

await a.ConfigureAwait(false);

After the program is done being paused, it will continue potentially on an entirely different thread with a different context. This is where the performance improvement would come from -- it could continue on on any available thread without having to restore the original context it started with.

Is this stuff confusing? Hell yeah! Can you figure it out? Probably! Once you have a grasp of the concepts, then move on to Stephen Cleary's explanations which tend to be geared more toward someone with a technical understanding of async/await already.

@veerendra gupta 2017-06-09 07:41:25

Lets say if all these task are returning a int and if I am using first task's result in second task(or some calculation) It would be wrong?

@Joe Phillips 2017-06-09 12:48:51

@veerendragupta yes. You would consciously choose not to run them asynchronously in that case (because they're not asynchronous). There are also a few other things to realize regarding configuration context which I won't go into here

@Jocie 2018-01-24 14:47:34

So await MethodCall() is an absolute waste? You might as well drop the await/async?

@Joe Phillips 2018-01-24 15:33:46

@Jocie Not quite. When you call await, I think it releases the thread back to the pool instead of holding it. This makes it available for use elsewhere while awaiting the return of the Task

@Bob Horn 2018-03-11 15:26:17

@JoePhillips I think what you just said is the essence of async/await. The calling thread is freed and can be used by other processes on the machine. When the await call is complete, a new thread is used to resume what the caller originally started. The caller is still waiting, but the benefit is that a thread is freed in the meantime. That's the benefit of async/wait?

@Bob Horn 2018-03-11 15:27:11

And I like your example in your answer, but what's missing is WHY the first block took 1 second, while the second block took 5. Can someone explain that?

@Joe Phillips 2018-03-12 01:37:16

@BobHorn I cleaned it up a bit I think. Have a look

@slowjams 2019-07-09 05:18:03

@JoePhillips so in your example, is the first block can be called asychronous and the second block should be called synchronous ? so aync/await still can run synchronously?

@Joe Phillips 2019-07-09 14:39:06

@slowjams Technically they're both asynchronous but the second example shows how you can run async tasks in a synchronous order

@serop 2019-07-14 12:51:36

attention .NET Core users - it does not have SynchronizationContext, and what may happen to you, async code working in .NET Core may not work properly in 'regular frameworks which do have the SynchronizationContext and you still need to use ConfigureAwait() call. Especially when you call async code from sync code (for example by calling Task.WaitAll() ), it causes deadlocks which are frustrating to figure out why.

@Blue Clouds 2018-09-08 06:29:55

For fastest learning..

  • Understand method execution flow(with a diagram): 3 mins

  • Question introspection (learning sake): 1 min

  • Quickly get through syntax sugar: 5 mins

  • Share the confusion of a developer : 5 mins

  • Problem: Quickly change a real-world implementation of normal code to Async code: 2 mins

  • Where to Next?

Understand method execution flow(with a diagram): 3 mins

In this image, just focus on #6 enter image description here

At #6 step: AccessTheWebAsync() has run out of work that it can do without a result from getStringTask. Therefore, AccessTheWebAsync uses an await operator to suspend its progress and give control back(yield) to the caller. AccessTheWebAsync returns a Task(of string return value) to the caller. The task represents a promise to produce a string result. But when will it return the call? a 2nd call again?

The caller of AccessTheWebAsync() did nothing but wait(it could have done some internal tasks and then waited if needed). So caller waiting for AccessTheWebAsync, and AccessTheWebAsync is waiting for GetStringAsync at the moment.

Remember, the method was already returned, it cannot return again(no second time). So how will the caller know? It is all about Tasks! Task was returned. Task was waited for (not method, not value). Value will be set in Task. Task status will be set to complete. Caller just monitors Task. Further reads for later here.

Question introspection for learning sake: 1 min

Let us adjust the question a bit:

How and When to use async and await Tasks?

Because learning Task automatically covers the other 2. For the sake of learning at least. Of course, this is an answer to your question about async and await.

Quickly get through syntax sugar: 5 mins

  • Before conversion(original method)

    internal static int Method(int arg0, int arg1) { int result = arg0 + arg1; IO(); // Do some long running IO. return result; }

  • Another Task-ified method to call the above method

    internal static Task<int> MethodTask(int arg0, int arg1) { Task<int> task = new Task<int>(() => Method(arg0, arg1)); task.Start(); // Hot task (started task) should always be returned. return task; }

Did we mention await or async? No. Call the above method and you get a task. Which you can monitor. You already know what the task returns.. an integer.

  • Calling a Task is slightly tricky. Let us call MethodTask()

    internal static async Task<int> MethodAsync(int arg0, int arg1) { int result = await HelperMethods.MethodTask(arg0, arg1); return result; }

We are 'awaiting' task to be finished. Hence the await. Since we use await, we must use async(mandatory) and MethodAsync with 'Async' as the prefix (coding standard). Further reads for later here

Share the confusion of a developer: 5 mins

A developer has made a mistake of not implementing Task but it still works! Try to understand the question and just the accepted answer provided here. Hope you have read and fully understood. Likewise in our example calling an already built MethodAsync() is way easier than implementing that method with a Task (MethodTask()) ourself. Most developers find it difficult to get their head around Tasks while converting a code to Asynchronous one.

Tip: Try to find an existing Async implementation (like MethodAsync or ToListAsync) to outsource the difficulty. So we only need to deal with Async and await (which is easy and pretty similar to normal code)

Problem: Quickly change a real-world implementation of normal code to Async operation: 2 mins

Code line shown below in Data Layer started to break(many places). Because we updated some of our code from .Net framework 4.2 to .Net core. We had to fix this in 1 hour all over the application!

var myContract = query.Where(c => c.ContractID == _contractID).First();


  1. EntityFrameWork nuget (it has QueryableExtensions)
  2. namespace = Microsoft.EntityFrameworkCore

code got changed like this

var myContract = await query.Where(c => c.ContractID == _contractID).FirstAsync();
  1. Method signature changed from

    Contract GetContract(int contractnumber)


    async Task<Contract> GetContractAsync(int contractnumber)

  2. calling method also got affected: GetContractAsync(123456); was called as GetContractAsync(123456).Result;

  3. We changed it everywhere in 30 minutes!

But the architect told us not to use EntityFrameWork library just for this! oops! drama! Then we made a custom Task implementation. Which you know how. Still easy!

Where to Next? There is a wonderful quick video we could watch about Converting Synchronous Calls to Asynchronous in ASP.Net Core, because that is likely the direction one would go after reading this.

@ABajpai 2018-08-05 17:21:39

On a higher level:

1) Async keyword enables the await and that's all it does. Async keyword does not run the method in a separate thread. The beginning f async method runs synchronously until it hits await on a time-consuming task.

2) You can await on a method that returns Task or Task of type T. You cannot await on async void method.

3) The moment main thread encounters await on time-consuming task or when the actual work is started, the main thread returns to the caller of the current method.

4) If the main thread sees await on a task that is still executing, it doesn't wait for it and returns to the caller of the current method. In this way, the application remains responsive.

5) Await on processing task, will now execute on a separate thread from the thread pool.

6) When this await task is completed, all the code below it will be executed by the separate thread

Below is the sample code. Execute it and check the thread id

using System;
using System.Threading;
using System.Threading.Tasks;

namespace AsyncAwaitDemo
    class Program
        public static async void AsynchronousOperation()
            Console.WriteLine("Inside AsynchronousOperation Before AsyncMethod, Thread Id: " + Thread.CurrentThread.ManagedThreadId);
            //Task<int> _task = AsyncMethod();
            int count = await AsyncMethod();

            Console.WriteLine("Inside AsynchronousOperation After AsyncMethod Before Await, Thread Id: " + Thread.CurrentThread.ManagedThreadId);

            //int count = await _task;

            Console.WriteLine("Inside AsynchronousOperation After AsyncMethod After Await Before DependentMethod, Thread Id: " + Thread.CurrentThread.ManagedThreadId);


            Console.WriteLine("Inside AsynchronousOperation After AsyncMethod After Await After DependentMethod, Thread Id: " + Thread.CurrentThread.ManagedThreadId);

        public static async Task<int> AsyncMethod()
            Console.WriteLine("Inside AsyncMethod, Thread Id: " + Thread.CurrentThread.ManagedThreadId);
            int count = 0;

            await Task.Run(() =>
                Console.WriteLine("Executing a long running task which takes 10 seconds to complete, Thread Id: " + Thread.CurrentThread.ManagedThreadId);
                count = 10;

            Console.WriteLine("Completed AsyncMethod, Thread Id: " + Thread.CurrentThread.ManagedThreadId);

            return count;

        public static void DependentMethod(int count)
            Console.WriteLine("Inside DependentMethod, Thread Id: " + Thread.CurrentThread.ManagedThreadId + ". Total count is " + count);

        static void Main(string[] args)
            Console.WriteLine("Started Main method, Thread Id: " + Thread.CurrentThread.ManagedThreadId);


            Console.WriteLine("Completed Main method, Thread Id: " + Thread.CurrentThread.ManagedThreadId);



@Stephen Marcus 2018-04-10 08:03:42

The answers here are useful as a general guidance about await/async. They also contain some detail about how await/async is wired. I would like to share some practical experience with you that you should know before using this design pattern.

The term "await" is literal, so whatever thread you call it on will wait for the result of the method before continuing. On the foreground thread, this is a disaster. The foreground thread carries the burden of constructing your app, including views, view models, initial animations, and whatever else you have boot-strapped with those elements. So when you await the foreground thread, you stop the app. The user waits and waits when nothing appears to happen. This provides a negative user experience.

You can certainly await a background thread using a variety of means:

Device.BeginInvokeOnMainThread(async () => { await AnyAwaitableMethod(); });

// Notice that we do not await the following call, 
// as that would tie it to the foreground thread.
Task.Run(async () => { await AnyAwaitableMethod(); });

The complete code for these remarks is at See the solution called AwaitAsyncAntipattern.sln.

The GitHub site also provides links to a more detailed discussion on this topic.

@geometrikal 2018-06-11 06:26:08

From what I understand, async / await is syntactic sugar for callbacks, it has nothing to do with threading. It is for non-CPU bound code, e.g. waiting for input or a delay. Task.Run should only be used for CPU-bound code…

@Don Cheadle 2018-07-01 20:41:49

The term "await" is literal, so whatever thread you call it on will wait for the result of the method before continuing. This is not true - maybe you meant Task.Wait()? When you use await, it sets the rest of the method as a continuation to be executed when whatever you await-ed is complete. It exits the method that you used it in, so the caller can continue. Then when the await-ed line is actually complete, it finishes the remainder of that method on some thread (usually a worker thread).

@Don Cheadle 2018-07-01 20:47:09

@geometrikal at the very core, async/await is about freeing up .NET Threads. When you await a truly-async operation (such as .NET's File.WriteAsync), it suspends the remainder of the method you used await in, so the caller can continue and potentially finish its purpose. There is no thread blocking or waiting for the await-ed operation. When the operation you awaited is complete, the remainder of the async/await method is put on a thread and executed (similar to a call-back idea).

@Weslley Rufino de Lima 2018-02-21 21:45:06

public static void Main(string[] args)
    string result = DownloadContentAsync().Result;

// You use the async keyword to mark a method for asynchronous operations.
// The "async" modifier simply starts synchronously the current thread. 
// What it does is enable the method to be split into multiple pieces.
// The boundaries of these pieces are marked with the await keyword.
public static async Task<string> DownloadContentAsync()// By convention, the method name ends with "Async
    using (HttpClient client = new HttpClient())
        // When you use the await keyword, the compiler generates the code that checks if the asynchronous operation is finished.
        // If it is already finished, the method continues to run synchronously.
        // If not completed, the state machine will connect a continuation method that must be executed WHEN the Task is completed.

        // Http request example. 
        // (In this example I can set the milliseconds after "sleep=")
        String result = await client.GetStringAsync("");


        // After completing the result response, the state machine will continue to synchronously execute the other processes.

        return result;

@vibs2006 2018-01-24 12:45:39

See this fiddle (and improve it if possible) for running a simple console application which shows usages of Task, Task.WaitAll(), async and await operators in the same program.

This fiddle should clear your execution cycle concept.

Here is the sample code

using System;
using System.Threading.Tasks;

public class Program
    public static void Main()
        var a = MyMethodAsync(); //Task started for Execution and immediately goes to Line 19 of the code. Cursor will come back as soon as await operator is met       
        Console.WriteLine("Cursor Moved to Next Line Without Waiting for MyMethodAsync() completion");
        Console.WriteLine("Now Waiting for Task to be Finished");       
        Task.WaitAll(a); //Now Waiting      
        Console.WriteLine("Exiting CommandLine");       

    public static async Task MyMethodAsync()
        Task<int> longRunningTask = LongRunningOperation();
        // independent work which doesn't need the result of LongRunningOperationAsync can be done here
        Console.WriteLine("Independent Works of now executes in MyMethodAsync()");
        //and now we call await on the task 
        int result = await longRunningTask;
        //use the result 
        Console.WriteLine("Result of LongRunningOperation() is " + result);

    public static async Task<int> LongRunningOperation() // assume we return an int from this long running operation 
        Console.WriteLine("LongRunningOperation() Started");
        await Task.Delay(2000); // 2 second delay
        Console.WriteLine("LongRunningOperation() Finished after 2 Seconds");
        return 1;


Trace coming from Output Window: enter image description here

@Dan Dinu 2013-11-14 18:55:19

When using async and await the compiler generates a state machine in the background.

Here's an example on which I hope I can explain some of the high-level details that are going on:

public async Task MyMethodAsync()
    Task<int> longRunningTask = LongRunningOperationAsync();
    // independent work which doesn't need the result of LongRunningOperationAsync can be done here

    //and now we call await on the task 
    int result = await longRunningTask;
    //use the result 

public async Task<int> LongRunningOperationAsync() // assume we return an int from this long running operation 
    await Task.Delay(1000); // 1 second delay
    return 1;

OK, so what happens here:

  1. Task<int> longRunningTask = LongRunningOperationAsync(); starts executing LongRunningOperation

  2. Independent work is done on let's assume the Main Thread (Thread ID = 1) then await longRunningTask is reached.

    Now, if the longRunningTask hasn't finished and it is still running, MyMethodAsync() will return to its calling method, thus the main thread doesn't get blocked. When the longRunningTask is done then a thread from the ThreadPool (can be any thread) will return to MyMethodAsync() in its previous context and continue execution (in this case printing the result to the console).

A second case would be that the longRunningTask has already finished its execution and the result is available. When reaching the await longRunningTask we already have the result so the code will continue executing on the very same thread. (in this case printing result to console). Of course this is not the case for the above example, where there's a Task.Delay(1000) involved.

@ammcom 2014-11-27 06:51:05

Any thread can't handle UI issues while in many examples we can access UI in the code after await, you have something wrong in your explanation

@codea 2015-01-01 11:24:46

I am a former VB6 programmer, and the await makes me think a little bit about the "Do Events" instruction that I used to tell the UI to refresh when performing an intensive loop. Am I right to think that way?

@Benison Sam 2015-03-08 17:28:26

Why do we have an "await" with the "Task.Delay(1000);" in LongRunningOperation async method?

@Camilo Martinez 2015-04-23 15:44:34

@codea In Eric Lippert's comments to the article he linked an introductory article to this topic where he specifically compares DoEvents strategy with async-await

@shelbypereira 2015-12-04 10:33:57

@BenisonSam thread is a bit old, but I had the same question and have been looking for an answer. Reason for the "await" is that if we omit the "await" the LongRunningOperationAsync() will return immediately. In fact the compiler will give a warning if we remove the await. Stephen Cleary's blog post… gives an execellent of the design discussions.

@gonzobrains 2015-12-04 18:06:17

Ahhh! The dreaded DoEvents() method!

@Davut Gürbüz 2016-05-08 20:25:42

This means if await task (longRunningTask here) is not finished its job yet and caller method (MyMethodAsync Task here)'s instance should be stored in a state machine and notified when job is over. It sounds like an observer pattern implementation which notifies a task end. If main thread is not in use is there any other thread production here? Which thread longRunningTask run on when I'm doing something else with main thread ?

@JohnB 2016-05-16 23:05:10

@BenisonSam because Task.Delay() implements async so it can be run asynchronously with the await keyword.

@Bruno Santos 2016-05-19 13:46:32

If every async method need to have an await inside of it, and a await can only be done on a methods with async, when does it stop?

@marczellm 2016-05-26 15:43:22

I have the same question as @DavutGürbüz: Which thread is longRunningTask running on when I'm doing something else on the main thread?

@user11081980 2016-06-06 22:18:11

You should get a job writing the MSDN documentation! Best explanation I've read. Thanks!

@Siyavash Hamdi 2016-07-15 01:51:44

@JohnB, Task.Delay() isn't implement async modifier (like public static Task Delay(int millisecondsDelay);) but as I understood all methods which in their output type have defined GetAwaiter are considered as asynchronous methods and awaitable as well. for example Task class has a method public TaskAwaiter GetAwaiter();. It means all methods which haveTask return type are awaitable.

@Krishna Deepak 2016-08-15 23:35:20

This answer is clearly wrong. These many upvotes will cause wrong understanding to many users. MS documentation clearly says, no other thread is used when just using async, await. Please somebody correct the answer. Due to this i wasted one whole day.

@Sandeep Shekhawat 2016-08-23 05:10:06

Task.Delay() is awaitable method which runs asynchronously. the async method needs to await method but await method could be either async or Task method.

@Izzy 2016-09-19 10:36:05

Since you awaited Task.Delay... didn't you just skip over it and instantly return 1 in the main thread?

@ToolmakerSteve 2017-02-02 23:52:02

@Izzy - No, what gets "immediately returned" by LongRunningOperationAsync is a task. That task will be suspended for 1000 ms, until await Task.Delay(1000) returns. At that time, await longRunningTask will complete, allowing Console.WriteLine(result) to run. [Perhaps I should not say the task is "suspended", as that sounds like it is tying up a thread. As I understand it, it is data - a description of how to continue - that is stored somewhere, but not tying up a thread.]

@El Mac 2017-06-19 08:55:10

@ammcom if the original Thread was the UI-Thread, the await will dispatch again to the UI-Thread. If the original Thread was NOT the UI-Thread, any other Thread from the can continue the execution. Hence you don't have to worry about accessing UI from a separate thread.

@El Mac 2017-06-19 09:11:03

@KrishnaDeepak when you use an async method, the method is executed synchronously until an await. Then after the await, the method is executed asynchronously. Sometimes you have to run a new thread explicitly with Task.Run and await it. The method runs first synchronously then asynchronously.

@Eric G 2018-09-14 19:29:01

@BrunoSantos At some point, you will call and async method in a context where you don't need to wait for it.

@ed22 2019-03-17 09:21:23

So it is running and awaiting a task in another task? We have "Main" task here + 2 more?!

@lazydeveloper 2017-08-31 18:40:12

In the following code, the HttpClient method GetByteArrayAsync returns a Task, getContentsTask. The task is a promise to produce the actual byte array when the task is complete. The await operator is applied to getContentsTask to suspend execution in SumPageSizesAsync until getContentsTask is complete. In the meantime, control is returned to the caller of SumPageSizesAsync. When getContentsTask is finished, the await expression evaluates to a byte array.

private async Task SumPageSizesAsync()
    // To use the HttpClient type in desktop apps, you must include a using directive and add a 
    // reference for the System.Net.Http namespace.
    HttpClient client = new HttpClient();
    // . . .
    Task<byte[]> getContentsTask = client.GetByteArrayAsync(url);
    byte[] urlContents = await getContentsTask;

    // Equivalently, now that you see how it works, you can write the same thing in a single line.
    //byte[] urlContents = await client.GetByteArrayAsync(url);
    // . . .

@Tone Škoda 2017-07-15 08:03:51

All the answers here use Task.Delay() or some other built in async function. But here is my example that use none of those async functions:

    // Starts counting to a large numbewr and then immediately displays message "i'm counting...". 
    // Then it waits for task to finish and displays "finished, press any key".
    static void asyncTest ()
        Console.WriteLine("Started asyncTest()");
        Task<long> task = asyncTest_count();
        Console.WriteLine("Started counting, please wait...");
        task.Wait(); // if you comment this line you will see that message "Finished counting" will be displayed before we actually finished counting.
        //Console.WriteLine("Finished counting to " + task.Result.ToString()); // using task.Result seems to also call task.Wait().
        Console.WriteLine("Finished counting.");
        Console.WriteLine("Press any key to exit program.");

    static async Task<long> asyncTest_count()
        long k = 0;
        Console.WriteLine("Started asyncTest_count()");
        await Task.Run(() =>
            long countTo = 100000000;
            int prevPercentDone = -1;
            for (long i = 0; i <= countTo; i++)
                int percentDone = (int)(100 * (i / (double)countTo));
                if (percentDone != prevPercentDone)
                    prevPercentDone = percentDone;
                    Console.Write(percentDone.ToString() + "% ");

                k = i;
        Console.WriteLine("Finished asyncTest_count()");
        return k;

@Jeffnl 2018-07-27 05:33:16

Thank you! the first answer that actually does some work instead of waiting.

@encoder 2018-12-29 19:04:53

thank you for showing task.Wait(); and how it can be used to avoid async/await hell :P

@user21306 2017-06-02 21:15:25

The way I understand it is also, there should be a third term added to the mix: Task.

Async is just a qualifier you put on your method to say it's an asynchronous method.

Task is the return of the async function. It executes asynchronously.

You await a Task. When code execution reaches this line, control jumps out back to caller of your surrounding original function.

If instead, you assign the return of an async function (ie Task) to a variable, when code execution reaches this line, it just continues past that line in the surrounding function while the Task executes asynchronously.

@Adriaan Stander 2013-01-22 09:39:00

Further to the other answers, have a look at await (C# Reference)

and more specifically at the example included, it explains your situation a bit

The following Windows Forms example illustrates the use of await in an async method, WaitAsynchronouslyAsync. Contrast the behavior of that method with the behavior of WaitSynchronously. Without an await operator applied to a task, WaitSynchronously runs synchronously despite the use of the async modifier in its definition and a call to Thread.Sleep in its body.

private async void button1_Click(object sender, EventArgs e)
    // Call the method that runs asynchronously.
    string result = await WaitAsynchronouslyAsync();

    // Call the method that runs synchronously.
    //string result = await WaitSynchronously ();

    // Display the result.
    textBox1.Text += result;

// The following method runs asynchronously. The UI thread is not
// blocked during the delay. You can move or resize the Form1 window 
// while Task.Delay is running.
public async Task<string> WaitAsynchronouslyAsync()
    await Task.Delay(10000);
    return "Finished";

// The following method runs synchronously, despite the use of async.
// You cannot move or resize the Form1 window while Thread.Sleep
// is running because the UI thread is blocked.
public async Task<string> WaitSynchronously()
    // Add a using directive for System.Threading.
    return "Finished";

@Dan Dinu 2013-01-22 09:51:24

thanks for the answer. But is WaitAsynchronouslyAsync() executed on a separate thread?

@Adriaan Stander 2013-01-22 09:56:34

I do belive so, from the section An await expression does not block the thread on which it is executing. Instead, it causes the compiler to sign up the rest of the async method as a continuation on the awaited task. Control then returns to the caller of the async method. When the task completes, it invokes its continuation, and execution of the async method resumes where it left off.

@Vimes 2013-04-12 19:49:01

According to this MSDN article, "The async and await keywords don't cause additional threads to be created.... an async method doesn't run on its own thread". My understanding is that at await keywords the framework skips ahead (back to the caller) to allow all possible independent code to run while waiting for long operations to finish. I think that means that once all independent code has run, if the long operation hasn't returned, it will block. I am just learning this now, though.

@MgSam 2013-11-14 19:02:16

@astander That is incorrect. It does not execute on a different thread. It is just schedules the continuation (the rest of the method) to be called when the timer used by Task.Delay fires.

@Jared Updike 2014-02-28 23:25:55

This answer is wrong because of the Sleep. See the accepted answer with await Task.Delay(1000); which has the correct behavior.

@Royi Namir 2014-04-29 08:47:59

@astander What if button1_Click were not async (and did not contain await) and WaitAsynchronouslyAsync stayed the same ? what would happen then ? would the GUI still freeze ??

@Nicolas 2016-11-04 10:16:24

@RoyiNamir No, the GUI does not freeze, but you get no result then.

@Dmitry G. 2016-10-04 16:16:30

is using them equal to spawning background threads to perform long duration logic?

This article MDSN:Asynchronous Programming with async and await (C#) explains it explicitly:

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.

@Vnuk 2013-01-22 09:32:54

I think you've picked a bad example with System.Threading.Thread.Sleep

Point of an async Task is to let it execute in background without locking the main thread, such as doing a DownloadFileAsync

System.Threading.Thread.Sleep isn't something that is "being done", it just sleeps, and therefore your next line is reached after 5 seconds ...

Read this article, I think it is a great explanation of async and await concept:

@Abdurrahim 2019-02-02 11:01:28

Why Sleep is bad example but Download is good example. It is like FooBar kind of thing when I see Thread.Sleep I understand there is some task that takes times. I think his question is relevant

@Gabriel Luci 2019-09-11 01:12:39

@Abdurrahim Thread.Sleep blocks the thread (the thread cannot do anything else but sit idle), but an async method does not. In the case of DownloadFileAsync, the thread can go and do something else until a reply comes from the remote server. A better placeholder for "some task that takes time" in an async method is Task.Delay, since that is actually asynchronous.

@Abdurrahim 2019-09-12 00:36:22

@GabrielLuci my objection is not about Delay vs Sleep; Your answer is looking more like a strawman answer; If you put this as a comment to the question that would be nothing I could object, but as an answer it smells more like a strawman answer. I think it is still fine to use async there even all calls he/she have to be making will be blocking calls; It won't invalidate all the purpose... Even all left will be syntactic sugar it counts as a valid case,

@Gabriel Luci 2019-09-12 01:01:19

This wasn't my answer. But to address your point: it depends on the purpose of the method. If he just wanted a method to call, he succeeded. But in this case he was trying to make a method that runs asynchronously. He did that by just using the async keyword. But his method still ran synchronously, and this answer explained perfectly why: because he didn't actually run any asynchronous code. Methods marked async still run synchronously up until you await an incomplete Task. If there is no await, then the method runs synchronously, and the compiler will warn you of that.

@MarkWalls 2015-07-17 15:36:15

Here is a quick console program to make it clear to those who follow. The "TaskToDo" method is your long running method that you want to make async. Making it run Async is done by the TestAsync method. The test loops method just runs through the "TaskToDo" tasks and runs them Async. You can see that in the results because they don't complete in the same order from run to run - they are reporting to the console UI thread when they complete. Simplistic, but I think the simplistic examples bring out the core of the pattern better than more involved examples:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace TestingAsync
    class Program
        static void Main(string[] args)

        private static async void TestLoops()
            for (int i = 0; i < 100; i++)
                await TestAsync(i);

        private static Task TestAsync(int i)
            return Task.Run(() => TaskToDo(i));

        private async static void TaskToDo(int i)
            await Task.Delay(10);

@sppc42 2015-08-13 09:32:13

Showing the above explanations in action in a simple console program -

class Program
    static void Main(string[] args)
        Console.WriteLine("Press any key to exit...");

    public async static void TestAsyncAwaitMethods()
        await LongRunningMethod();

    public static async Task<int> LongRunningMethod()
        Console.WriteLine("Starting Long Running method...");
        await Task.Delay(5000);
        Console.WriteLine("End Long Running method...");
        return 1;

And the output is:

Starting Long Running method...
Press any key to exit...
End Long Running method...


  1. Main starts the long running method via TestAsyncAwaitMethods. That immediately returns without halting the current thread and we immediately see 'Press any key to exit' message
  2. All this while, the LongRunningMethod is running in the background. Once its completed, another thread from Threadpool picks up this context and displays the final message

Thus, not thread is blocked.

@StudioX 2018-11-23 07:05:38

"Press any key to exit..." will be showed in which part of output?

@StudioX 2018-11-23 07:07:58

and what's the usage of (return 1)? is it necessary?

@Kuba Do 2019-10-28 14:35:45

@StudioX i think it must have return type integer

@Lex Li 2014-09-08 02:06:42

This answer aims to provide some info specific to ASP.NET.

By utilizing async/await in MVC controller, it is possible to increase thread pool utilization and achieve a much better throughput, as explained in the below article,

In web applications that sees a large number of concurrent requests at start-up or has a bursty load (where concurrency increases suddenly), making these web service calls asynchronous will increase the responsiveness of your application. An asynchronous request takes the same amount of time to process as a synchronous request. For example, if a request makes a web service call that requires two seconds to complete, the request takes two seconds whether it is performed synchronously or asynchronously. However, during an asynchronous call, a thread is not blocked from responding to other requests while it waits for the first request to complete. Therefore, asynchronous requests prevent request queuing and thread pool growth when there are many concurrent requests that invoke long-running operations.

@atlaste 2013-01-22 10:16:25

To be honest I still think the best explanation is the one about future and promises on the Wikipedia:

The basic idea is that you have a separate pool of threads that execute tasks asynchronously. When using it. The object does however make the promise that it will execute the operation at some time and give you the result when you request it. This means that it will block when you request the result and hasn't finished, but execute in the thread pool otherwise.

From there you can optimize things: some operations can be implemented async and you can optimize things like file IO and network communication by batching together subsequent requests and/or reordering them. I'm not sure if this is already in the task framework of Microsoft - but if it isn't that would be one of the first things I would add.

You can actually implement the future pattern sort-of with yields in C# 4.0. If you want to know how it works exactly, I can recommend this link that does a decent job: . However, if you start toying with it yourself, you will notice that you really need language support if you want to do all the cool things -- which is exactly what Microsoft did.

Related Questions

Sponsored Content

29 Answered Questions

[SOLVED] How to enumerate an enum

17 Answered Questions

[SOLVED] Using async/await with a forEach loop

33 Answered Questions

[SOLVED] How can I upload files asynchronously?

61 Answered Questions

[SOLVED] How do I calculate someone's age in C#?

  • 2008-07-31 23:40:59
  • Jeff Atwood
  • 577077 View
  • 1765 Score
  • 61 Answer
  • Tags:   c# .net datetime

36 Answered Questions

[SOLVED] How do I return the response from an asynchronous call?

7 Answered Questions

[SOLVED] async/await - when to return a Task vs void?

39 Answered Questions

29 Answered Questions

[SOLVED] What is a NullReferenceException, and how do I fix it?

24 Answered Questions

[SOLVED] How would I run an async Task<T> method synchronously?

6 Answered Questions

[SOLVED] HttpClient.GetAsync(...) never returns when using await/async

Sponsored Content