Roslyn: Incorrect CS4014 shown when using the async method with System.Linq.Expression

Created on 21 Feb 2019  路  4Comments  路  Source: dotnet/roslyn

Here is the code snippet that clearly demonstrates the issue:

class Program {
    static void Main(string[] args) {
        RaiseCanExecuteChanged(() => Load());// <<< illegal CS4014 here
    }
    static async Task Load() {
        await Task.Delay(1000);
    }
    static void RaiseCanExecuteChanged(Expression<Action> selector) {
        /* ... */
    }
}

The impact of this issue:

it is impossible to compile the solution when "Threat warnings as errors" level is set to all(our default settings).

_This issue has been moved from https://developercommunity.visualstudio.com/content/problem/447121/incorrect-cs4014-show-when-using-the-async-method.html
VSTS ticketId: 787866_
_These are the original issue comments:_
(no comments)
_These are the original issue solutions:_
(no solutions)

Area-Compilers Developer Community Resolution-By Design

All 4 comments

It is possible to use a #pragma to suppress the warning.

This is by design. The warning is correct. Suppress it if you don't want it.

@gafter
Hi Neal,

This is by design.

Could you please to provide a bit more detailed description of this design?

Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the 'await' operator to the result of the call.

There is no method-call here. There is no execution. There is nothing "awaitable" at all.

Under the syntax-sugar there is a simple object's construction only:

    var method = typeof(Program).GetMethod("Load", BindingFlags.NonPublic | BindingFlags.Static);
    RaiseCanExecuteChanged(
        Expression.Lambda<Action>(
            Expression.Call((Expression)null, method))
        );

So I really do not understand why this warning is shown.

The method call in the source program is Load(). Its return type is awaitable. It can be executed, and the point of the warning is that this may be a misuse of the API.

Since it is inside a (expression) lambda, it may or may not be executed, but the compiler does not and should not track whether it is actually invoked.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

codingonHP picture codingonHP  路  3Comments

nlwolf picture nlwolf  路  3Comments

marler8997 picture marler8997  路  3Comments

AdamSpeight2008 picture AdamSpeight2008  路  3Comments

orthoxerox picture orthoxerox  路  3Comments