1

The .Net article on Tasks shows two following two code snippets, one using await and the other using Task.Wait and says both are "functionally equivalent".

Isn't that technically incorrect then? Can someone please clarify?

Also if Tasks are supposed to be asynchronous and form the basis for Asynchronous Programming (TPL), why would ASP.Net allow a synchronous Wait on them anyway? Doesn't that kind of violate their main utility?

using System;
using System.Threading.Tasks;

public class Example
{
   public static async Task Main()
   {
      await Task.Run( () => {
                                  // Just loop.
                                  int ctr = 0;
                                  for (ctr = 0; ctr <= 1000000; ctr++)
                                  {}
                                  Console.WriteLine("Finished {0} loop iterations",
                                                    ctr);
                               } );
   }
}
// The example displays the following output:
//        Finished 1000001 loop iterations
using System;
using System.Threading.Tasks;

public class Example
{
   public static void Main()
   {
      Task t = Task.Factory.StartNew( () => {
                                  // Just loop.
                                  int ctr = 0;
                                  for (ctr = 0; ctr <= 1000000; ctr++)
                                  {}
                                  Console.WriteLine("Finished {0} loop iterations",
                                                    ctr);
                               } );
      t.Wait();
   }
}
// The example displays the following output:
//        Finished 1000001 loop iterations

The article should explain the differences between the two calls clearly.

3
  • Unfortunately, the topic of asynchrony is so big that no single article can do it justice, but if we focus on the explicit details present in the article, and in particular the two pieces of code you're asking about, can we answer your question? Yes, we can, and yes, they are functionally equivalent in this case. No, await X and Task.Run(...).Wait() are not equivalent as they do things vastly different, but in this case it doesn't matter. Commented Dec 6, 2018 at 14:57
  • The task returned by your asynchronous Main method will be waited upon through code similar to Main().GetAwaiter().GetResult(), which is doing the same thing as .Wait(), it will block the calling thread until your task completes. So whether you write the code that blocks the thread while it waits, or you let the framework (or the compiler magic in the case of async Main) do it for you amounts to the same thing, the program main thread will block, waiting for your task to complete. Commented Dec 6, 2018 at 14:58
  • @LasseVågsætherKarlsen I would argue that in this specific case the article is worded so bad as to be quite misleading, even if it's technically correct. If I didn't already know a bunch of information not explained there, I'd come away with a lot of incorrect conclusions. While no single article can explain everything, they can at least not be misleading and leave you unsure about details not covered, rather than with incorrect assumptions. Commented Dec 6, 2018 at 15:03

1 Answer 1

7

Isn't that technically incorrect then?

No, because it's being very specific. It's not saying that writing an async method that awaits a task is always the same as just synchronously waiting on that task, it's only referring to very specifically the case of an async Main method as an entry point for the application. When you make the Main method async, it just synchronously waits on the returned task, making it functionally equivalent to just synchronously waiting on the task inside the method instead of making the method async only in that one exact situation.

(You could also make an argument that's it's just trying to say that StartNew with the parameters provided and Run are equivalent, and isn't intending to refer to the difference between the method being async versus synchronously waiting.)

why would ASP.Net allow a synchronous Wait on them anyway?

Task wasn't created exclusively to be a representation of work done asynchronously. It was designed to do that and also to synchronously work in parallel using multiple threads. When you're using tasks for asynchrony, you should basically never be using Wait or other synchronous blocking mechanism, but if you're using it to do multithreaded work synchronously, it's useful. You could make a [good] argument that they should have kept those concepts separate, but they didn't, and it's way too late to change it now.

Doesn't that kind of violate their main utility?

Yes, yes it does. Which is why I'm not a fan of this implementation, and would have preferred they'd implemented it differently. But they didn't.

The article should explain the differences between the two calls clearly.

Yes it should.

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

Comments

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.