1

I need a little rule about correct usage of await. Run this code in .net core c# 7.2:

static class Program { static async Task<string> GetTaskAsync(int timeout) { Console.WriteLine("Task Thread: " + Thread.CurrentThread.ManagedThreadId); await Task.Delay(timeout); return timeout.ToString(); } static async Task Main() { Console.WriteLine("Main Thread: " + Thread.CurrentThread.ManagedThreadId); Console.WriteLine("Should be greater than 5000"); await Watch(NotParallel); Console.WriteLine("Should be less than 5000"); await Watch(Parallel); } public static async Task Parallel() { var res1 = GetTaskAsync(2000); var res2 = GetTaskAsync(3000); Console.WriteLine("result: " + await res1 + await res2); } public static async Task NotParallel() { var res1 = await GetTaskAsync(2000); var res2 = await GetTaskAsync(3000); Console.WriteLine("result: " + res1 + res2); } private static async Task Watch(Func<Task> func) { var sw = new Stopwatch(); sw.Start(); await func?.Invoke(); sw.Stop(); Console.WriteLine("Elapsed: " + sw.ElapsedMilliseconds); Console.WriteLine("---------------"); } } 

As you all can see the behavior of two methods are different. It's easy to get wrong in practice. So i need a "thumb rule".

Update for real men Please, run code. And explain please why Parallel() runs faster than NonParallel().

Results, for ladies.

7
  • 5
    What exactly is your question ? Commented Apr 20, 2018 at 12:03
  • updated ........ Commented Apr 20, 2018 at 12:08
  • Are you looking for something like "Only await tasks in sequence if one depends on the other"? It's still not clear what the question is. Commented Apr 20, 2018 at 12:09
  • juharr - it seems a good explanation. Please move it into the answers Commented Apr 20, 2018 at 12:11
  • What 'rule of thumb' are you asking for? Task is something that may yield a result if you await for it. Until then, it's just an object which does nothing. In your NonParallel method you don't even have a second task until the first one yields, so of course these methods are totally different. Commented Apr 20, 2018 at 12:23

1 Answer 1

3

While calling GetTaskAsync without await, you actually get a Task with the method to execute (that is, GetTaskAsync) wrapped in. But when calling await GetTaskAsync, execution is suspended until the method is done executing, and then you get the result.

Let me be more clear:

var task = GetTaskAsync(2000); 

Here, task is of type Task<string>.

var result = await GetTaskAsync(2000); 

Here result is of type string.

So to address your first interrogation: when to await your Tasks really depends on your execution flow.

Now, as to why Parallel() is faster, I suggest your read this article (everything is of interest, but for your specific example, you may jump to Tasks return "hot").

Now let's break it down:

The await keyword serves to halt the code until the task is completed, but doesn't actually start it.

In your example, NotParallel() will take longer because your Tasks execute sequentially, one after the other. As the article explains:

This is due to the tasks being awaited inline.

In Parallel() however...

the tasks now run in parallel. This is due to the fact that all [tasks] are started before all [tasks] are subsequently awaited, again, because they return hot.

About 'hot' tasks

I suggest your read the following: Task-based Asynchronous Pattern (TAP)

The Task Status section is of interest here to understand the concepts of cold and hot tasks:

Tasks that are created by the public Task constructors are referred to as cold tasks, because they begin their life cycle in the non-scheduled Created state and are scheduled only when Start is called on these instances.

All other tasks begin their life cycle in a hot state, which means that the asynchronous operations they represent have already been initiated

I invite you to read extensively about async/await and Tasks. Here are a few resources in addition to the ones I provided above:

Asynchronous Programming in C# 5.0 part two: Whence await?

Async/Await - Best Practices in Asynchronous Programming

Async and Await

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

1 Comment

Nice articles linked.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.