0

I don't know if this question is dumb or not but I've seen a lot of different scenarios of async, await and sync methods. All I understand is that you're simply not "blocking the thread" from doing other tasks.

But when you're using an await on a task isn't that just simply waiting for the value to come back and in that case sync synchronous?

I'm using the .NET framework

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Tobbin2
  • 115
  • 2
  • 7
  • 1
    Might help if you identify which specific implementation of async you're asking about (e.g. .NET, javascript, etc). But in most implementations I'm familiar with, the point of the await is that it's not keeping a thread blocked with no work to do whilst the wait is happening. – Damien_The_Unbeliever Dec 18 '20 at 08:39
  • Ooh yea sorry i was using .Net ill update that, aah okej so it allows other processes to run. It doesn't really help my application then? – Tobbin2 Dec 18 '20 at 09:04
  • 8
    You might want to read [There is no thread](https://blog.stephencleary.com/2013/11/there-is-no-thread.html) then. – Damien_The_Unbeliever Dec 18 '20 at 09:06
  • 1
    They aren't the same thing at all, no matter the language or runtime (async/await is used in JavaScript and Kotlin too). In all languages, `await` means the original thread is free to do other things until `await` completes. Once that's done, execution may resume on the original thread (in desktop apps, browsers) or a new thread may be used whose state is the same as the original's (web apps) – Panagiotis Kanavos Dec 18 '20 at 09:10
  • Say you are filling out a form and need information from third party. Synchronous: You call the 3rd party when you're at that field in the form, then you wait until you get the information, you fill in the field, and move on. Asynchronous: You call the 3rd party when you're at that field in the form. Then you put the form aside and do something else until you get the information, then you pick up the form again and continue where you left off. The `await` keyword, along with classes in the runtime does the "pick up the form again and continue" for you. – Lasse V. Karlsen Dec 21 '20 at 08:22
  • Relevant: [How do yield and await implement flow of control in .NET?](https://stackoverflow.com/questions/42287737/how-do-yield-and-await-implement-flow-of-control-in-net) – John Wu Dec 21 '20 at 08:25

4 Answers4

2

You can think that by the await keyword you are immediately returning a Task (or similar) instead of the actual value (see my similar answer on JS). We must return a Task or similar since the actual return value is probably not known yet...

To illustrate the returning to the caller, here's the example from my other answer translated to C#:

class Program
{
    static async Task<string> MyAsyncFunc()
    {
        int i;

        for( i = 0; i < 1000000; i++ ) ; // create some synchronous delay

        // Create an asynchronous task that we can await on later...
        var innerTask = ( ( Func<Task<string>> )( async () => {
            await Task.Delay( 1000 );
            return "done!";
        } ) )();

        Console.WriteLine( "message inside f before returning, still synchronous, i = " + i );

        // let's await and at the same time return a Task to the caller
        var result = await innerTask;
        Console.WriteLine( "message inside f after await, asynchronous now" );

        Console.WriteLine( result ); // "done!"

        return "function finished";
    }

    static void Main()
    {
        var myresult = MyAsyncFunc();
        Console.WriteLine( "message outside f, immediately after calling f" );
        System.Threading.Thread.Sleep( 2000 ); // Create delay to prevent exit before asynchronous writing of lines.
    }
}

The corresponding output is:

message inside f before returning, still synchronous, i = 1000000
message outside f, immediately after calling f
message inside f after await, asynchronous now
done!

Note that Main() already continues executing after the function call well before the actual return value "function finished" is returned.

Simo Kivistö
  • 4,247
  • 3
  • 38
  • 42
1

When an await is encountered the execution doesn't progress but the thread executing the code can do other things and can come back later to continue.

With asynchronous operations a web server can serve more requests then threads it has because when processing of a request gets 'blocked' - to for example get something from the database - the thread can pick up another request and start processing it.

I hope that this, from What happens under the covers, helps to illustrate the difference:

On the C# side of things, the compiler transforms your code into a state machine that keeps track of things like yielding execution when an await is reached and resuming execution when a background job has finished.

tymtam
  • 31,798
  • 8
  • 86
  • 126
1

when you're using an await on a task isn't that just simply waiting for the value to come back and in that case sync synchronous?

One way to think of it is that the method waits for the asynchronous operation to complete, but the thread does not. Asynchronous code frees up threads, which gives you one of two benefits, depending on the kind of application you're writing:

  • GUI apps are able to keep their UI thread free, preventing the "frozen UI" / "application isn't responding" problems.
  • ASP.NET (and other server) apps are able to keep more threads available in their thread pool, which means they can scale more quickly and scale further (i.e., handle more simultaneous requests).

Is synchronous and await asynchronous just not the same thing?

The code does look similar, and it's done that way on purpose (to make asynchronous code easier to write and maintain). But the similarity is actually due to the serial nature of operations: A() then B() is similar to await A() then await B(). So it's the serial/imperative nature of the code that is similar; they are completely different in terms of synchronous vs asynchronous.

Stephen Cleary
  • 437,863
  • 77
  • 675
  • 810
1

when you're using an await on a task isn't that just simply waiting for the value to come back and in that case sync synchronous?

There is a fundamental misunderstanding here. An await is not a Wait() instruction. It is closer to a return. If the task isn't finished yet, await returns control to the caller immediately.

The rest of your method is posted as a separate task, with no guarantee when it will execute. That is what makes it asynchronous.

John Wu
  • 50,556
  • 8
  • 44
  • 80