3

I read many articles on async and await(mostly from msdn - which is good actually). There is still one question that bothers me and I could not find the answer.

If there is an await statement on a task then the control is returned to its caller until it is awaited again in the caller. In that case is this time consuming task getting executed in a separate thread? If not then how is it getting executed parallel to the main thread.

async Task<string> GetContentsAsync()
{
    int sample = 0;
    HttpClient client = new HttpClient();
    Task<string> contents = client.GetStringAsync("http://www.microsoft.com");
            
    string data = await contents;
    return data;
}

I hope my question is clear.

2

2 Answers 2

5

In that case is this time consuming task getting executed in a separate thread?

There are two kinds of tasks. Some Tasks have code to execute, and they run on some thread. Other Tasks do not execute code; they just represent some future event.

The "event tasks" are used a lot by async, particularly in I/O scenarios. In your example, you're executing an HTTP GET. GetStringAsync will send the HTTP request and then return an "event task" that completes when the response is received. While the HTTP request is in flight and being processed by the server, there's no code for the client to execute for that request. So there's no thread required, and none is used.

Also see my answer here.

4

It depends on how the task is created, but no, tasks are not inherently executed on a separate thread automatically. Some helper methods, like Task.Run for example, can help you make sure a task is put on a separate thread (the thread pool in this case).

Remember that a GUI application, let's say WinForms specifically, runs a so-called event loop. In WinForms this happens behind your back, in the Application.Run call. This event loop receives events like clicks and invokes your handlers. The thread that this loop executes on is referred to as "the GUI thread". In WinForms, it's the thread that creates all the controls, and hence also the only thread allowed to touch those controls.

When you create a task using the async modifier on a method, that code is also scheduled to execute via this event loop. It's just queued up. Just like the good old Invoke calls. So once your event handler returns, eventually the event loop gets to that queued up task, executes it, and then executes the rest of the method that followed the await. No parallelism here.

However, there are other ways to create tasks; calling an async method is just one way. Task.Run creates tasks that are put on separate threads. GetStringAsync you show in your example will actually run in parallel with whichever thread invoked the task.

8
  • If I dont explicitly use Task.Run in that case how is it executed?
    – ckv
    Commented Sep 30, 2013 at 13:10
  • In the sample code I have provided How would the execution be?
    – ckv
    Commented Sep 30, 2013 at 13:15
  • 1
    orthogonal to parallelism? <blink>
    – Liam
    Commented Sep 30, 2013 at 13:16
  • 1
    @Liam I just meant that whether you use async or not, and whether you use parallelism or not, are independent concepts. Try it; create an async button handler, another async method that modifies the GUI, and await the latter from the former. You'll see that all methods here will execute on the GUI thread. With zero parallelism, but using async. Commented Sep 30, 2013 at 13:25
  • 1
    @ckv yes, it runs in a thread - that one important thread that's known as the "GUI thread"; the only thread allowed to modify the UI controls. Commented Sep 30, 2013 at 13:27

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.