Michael Alexander
Michael Alexander

Reputation: 327

Why doesn't Task.Factory.StartNew() throw a compiler warning for await?

In visual studio 2012 and (I'm assuming) beyond, calls to async functions that are not awaited come up with warnings, i.e.

public static async Task FunctionAsync()
{
    await Task.Delay(10);
}

public static void SyncCaller()
{
    FunctionAsync();
}

SyncCaller's only line of code will show a compiler warning: "Because this call is not awaited, the current method continues to run before the call is completed."

However, if I rewrite SyncCaller():

public static void SyncCaller()
{
    Task.Factory.StartNew(() => {  });
}

There's no such warning, but it's very clear from StartNew's documentation that it returns an awaitable Task. So, what am I missing? Why is StartNew not warning me of my possible mistake?

Furthermore, if someone would be kind enough to comment on my question and point me in the direction of some discussion about how the await operator works under the covers, I would be much obliged. The syntax seems to be designed to hide a LOT, as I can write a method that returns Tasks, when the method body at no point creates any such thing.

EDIT: Others seem to think that you cannot await what StartNew returns. To give an example:

    public static async void SyncCaller()
    {
        await Task.Factory.StartNew(() => { });
    }

That method correctly awaits the completion of the Task that StartNew returns, so I do not think StartNew is an exception to the new asynchronous model.

Upvotes: 3

Views: 615

Answers (2)

Michael Alexander
Michael Alexander

Reputation: 327

Selman22's answer is correct and I will award him the answer, but I would like to re-write it, as I did not understand his point right away:

I erroneously thought the async/await model enforced the rule that any method that returns a Task will throw a compiler warning about not awaiting it. However, if I invoke the following function:

    public static Task TaskProducer()
    {
        return Task.Delay(10);
    }

The compiler gives us no such warning. This makes sense, as Tasks exist for purposes beyond the new async/await syntax. We are allowed to have Tasks that do not conform to the async/await pattern.

Upvotes: 0

Selman Genç
Selman Genç

Reputation: 101681

If you make your method async then you will get the warning you want, this code gives the warning:

public static async void SyncCaller()
{
    Task.Factory.StartNew(() => { });
}

Since it is not possible to await in a non-async method compiler doesn't warn you about awaiting, because you can't await without making your method async.So compiler can't suggest you something that is illegal.

Ofcourse this might cause the same unexpected behaviour that the warning tries to avoid.Compiler could say first make your method async then await this call, but then that would be too much suggestions.

Upvotes: 4

Related Questions