Will every ‘await’ operator result in a state machine?

Please consider the following code:

public async Task<string> GetString()
{
    //Some code here...
    var data = await A();
    //Some more code...
    return data;
}
private async Task<string> A()
{
    //Some code here..
    var data = await B();
    //manipulating data...
    return data;
}
private async Task<string> B()
{
    //Some code here..
    var data = await C();
    //manipulating data...
    return data;
}
private async Task<string> C()
{
    //Some code here..
    var data = await FetchFromDB();
    //manipulating data...
    return data;
}
private async Task<string> FetchFromDB()
{
    return await SOME_HTTP_REQUEST;
}

This code demonstrate a most basic functionality – nested async methods.
Will every method get translate into a state machine? Or is the compiler sophisticated enough to generate a more efficient structure?
In some of my projects, there are ~20 methods between the UI/WebAPI and the I/O call – does that affect the trade-off between the async-await overhead (such as the state machine) and the non-blocking thread benefits?
I mean, if, for example, the overhead of 4 state machines (4 nested async methods) equals to 50ms of blocking I/O (in terms of trade-off), will 20 state machine be equal to longer I/O’s delay (250ms)?

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

await doesn’t matter in this case. Each async method will generate a state machine (even if it has no awaits at all).

You can see that with this TryRoslyn example.

If you have cases where a state machine isn’t needed, where the method doesn’t really need to be async like this one for example:

private async Task<string> D()
{
    var data = await FetchFromDB();
    return data;
}

You can remove the async keyword and the state machine that comes with it:
private Task<string> D()
{
    return FetchFromDB();
}

But otherwise, you actually need the state machine and an async method can’t operation without it.

You should note that the overhead is quite small and is usually negligible compared to the resources saved by using async-await. If you realize that’s not the case (by testing) you should probably just make that operation synchronous.

Method 2

Every method is going to have a state machine, yes.

Keep in mind that the “overhead” of the state machine is primarily the allocation of one object (that and a few gotos, which are going to be quite fast), so any type of “optimization” that you perform to remove it is the same as not creating an instance of a class once.

As to whether or not it’s cost is greater or less than doing the work synchronously, that’s something you’re going to need to do performance benchmarks on given the specifics of your application and hardware to know for sure.

Method 3

Will every method get translate into a state machine? Or is the
compiler sophisticated enough to generate a more efficient structure?

No, the compiler will generate a state-machine for each of these calls. The compiler doesn’t check the semantical call-chain of your methods. It will generate a state-machine on a method basis only.

You can see that clearly when looking at the compiled code:

Compiler generated code:

does that affect the trade-off between the async-await overhead (such
as the state machine) and the non-blocking thread benefits?

You will have to test your code in order to be able to say that. Generally, async IO is good when you need through-put. If your async methods are going to be hit concurrently by multiple callers, you’ll be able to see the benefits. If not, you might not see any effect of a performance gain. Again, benchmark your code.


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x