What harm does declaring a method async cause if the method doesn't make asynchronous calls?

Viewed 116

I've come across some code that is marked as "async" but doesn't make any asynchronous calls. A dumbed-down version:

public async Task<int> NotReallyAsynchronous() {
    // Some code... var someInt = ...;
    return someInt;
}

I know this can lead to a chain of awaits to appear throughout the codebase, but other than that, what are the dangers of it?

It results in a compiler warning, and I intend to change the code so it no longer has the async modifier, but I am interested in knowing if there are other reasons that it is problematic.

1 Answers

One reason is that the generated IL (intermediate language) code is more costly when a function is declared async. The C# async/await feature is not a feature that's available at the IL level, so the compiler has to generate some extra code to make that feature work in IL. This could result in less efficient performance (both in speed and memory usage) at runtime.

For example, compare the two methods in this SharpLab demo.

public async Task<int> NotReallyAsynchronous(){
    return 5;
}

public int Sync(){
    return 7;
}

In IL, Sync is just a single method, short enough to copy here:

.method public hidebysig 
        instance int32 Sync () cil managed 
    {
        // Method begins at RVA 0x208b
        // Code size 2 (0x2)
        .maxstack 8

        IL_0000: ldc.i4.7
        IL_0001: ret
    } // end of method C::Sync

Whereas NotReallyAsynchronous has a method, but also a nested type <NotReallyAsynchronous>d__0 containing two fields and two methods, the latter of which are not trivial and too large for me to paste here. Maybe not a huge amount of code generally speaking, but clearly if you can reduce it (across a large number of cases) by omitting async, it could have an impact.

Related