Peter D
Peter D

Reputation: 11

Using C#, why await an Async method when a synchronous version is available?

There are plenty of explanations of await and async, now available in C#; but nothing seems to explain why this...

using (XmlReader reader = XmlReader.Create(stream, settings))
{
    while (await reader.ReadAsync())
    {
        // Do something
    }
}

is better than this...

using (XmlReader reader = XmlReader.Create(stream, settings))
{
    while (reader.Read())
    {
        // Do something
    }
}

In other words, if you have no intention of doing other stuff while you await for the ...Async method to do its thing, why use it all? If a synchronous method is available, why not just use that?

This Async example is taken from: https://learn.microsoft.com/en-us/dotnet/api/system.xml.xmlreader?view=netframework-4.7.1

EDIT: Having read the question and answer to which this was thought to be a duplicate, they did not help. I was asking specifically about the simple case of having await on the same line as the Async method being called. My question has been answered below. Thank you all!

Upvotes: 0

Views: 705

Answers (4)

Harald Coppoolse
Harald Coppoolse

Reputation: 30492

you wrote:

if you have no intention of doing other stuff while you await ...

Well maybe your procedure has no intention of doing other stuff while you await, but your caller might want to!

If you call await for a task, and the task is not completed yet, your thread goes up the call stack to see if your caller is awaiting your task, and if not, the thread starts executing statements until he has to await. The thread goes up the call stack again.

So even if you don't have to do something useful, if you think there might be the slightest chance that your caller might want to do something instead of waiting until you are ready, better make your function async whenever you have the choice to call async functions. If you think that your class will be used widely, consider creating an async and a non-async version

Upvotes: 1

Yannick Meeus
Yannick Meeus

Reputation: 5910

Fundamentally, using an asynchronous method call will not block the thread, which is a finite resource on any machine. Let's say you have a method call that might take 3 seconds to complete due to network latency, heavy database workload, etc. If you call this method synchronously, your thread is actually sitting there waiting for the results to come back, oblivious to the rest of your application.

Asynchronous method calls (or async/await, as it's colloquially known and called) are non-blocking. So if your executing thread encounters a method that indicates it can be awaited, it will (and I'm vastly oversimplifying things here) put a flag in the sand and tell the system to just do the thing and give me a call when you're done.

Now you're probably thinking, "But wait! Doesn't that mean another thread has to do the job the current thread just delegated?!" and you'd be correct.

This is where the concept of foreground and background threads comes in. An example of a foreground thread would be something like the thread handling a web API call in the controller, or a UI rendering thread.

Blocking these threads is detrimental for several reasons, in the case of API threads you're basically narrowing the window of how many requests per second you can handle at any given time. In the UI case, it might stall the rendering for several seconds while it's doing work in the background.

So what are the positives and negatives in general? You're distributing your thread workload more evenly when using async/await, at the detriment of memory overhead (something's going to have to remember where all the flags in the sand are, and keep track of when the process can continue).

When people say it's making the application more performant, this is true by making it more concurrent, but not necessarily faster.

To address the comment left by Mihir Dave:

Misuse of async/await would include trying to apply it to pure computational methods (eg. no I/O, purely CPU bound). At that point you're adding a lot of complexity and overhead for no benefit. Another bad application is not embracing it top to bottom, if you start trying to "syncify" async methods, or "asyncify" sync methods, the risk for deadlocks increases dramatically. The latter is quite common when working with outdated APIs, that may not expose async methods.

An extensive read about async/await read would be Q: why-shouldnt-all-functions-be-async-by-default

Upvotes: 6

Titian Cernicova-Dragomir
Titian Cernicova-Dragomir

Reputation: 250156

It depends on your use case. Using await will free up the current thread to do other things. If this thread is the UI thread in a desktop application, you must free it to process the UI. If you are on a webserver you will want to free up the thread to process other requests, threads are not free, they take up 1MB if memory for stack space.

If you are not concerned about any of those scenarios calling the sync version is ok as well

Upvotes: 0

Alex Wiese
Alex Wiese

Reputation: 8370

It will free up a thread to do other things (potentially) instead of spinning and waiting for the IO to complete. For web applications this helps the application scale by using these threads to handle more requests. For UI applications it allows the main (UI) thread to keep the application responsive to user input.

You can read more about the benefits of async in .NET here.

Upvotes: 2

Related Questions