为什么没有Task.Factory.StartNew()为await抛出编译器警告?

时间:2014-10-07 22:35:22

标签: c# .net asynchronous

在visual studio 2012和(我假设)之外,对不等待的异步功能的调用会产生警告,即

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

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

SyncCaller唯一的代码行将显示编译器警告:“因为不等待此调用,所以当前方法在调用完成之前继续运行。”

但是,如果我重写SyncCaller():

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

没有这样的警告,但从StartNew的文档中可以清楚地看出它返回了一个等待的任务。那么,我错过了什么?为什么StartNew没有警告我可能的错误?

此外,如果有人愿意对我的问题发表评论,并指出我在讨论await运算符如何在幕后工作的方式,我将非常感激不尽。语法似乎被设计为隐藏LOT,因为我可以编写一个返回Tasks的方法,当方法体在任何时候都不会创建任何这样的东西。

编辑: 其他人似乎认为你无法等待StartNew返回的内容。举个例子:

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

该方法正确等待StartNew返回的Task的完成,所以我认为StartNew不是新异步模型的例外。

2 个答案:

答案 0 :(得分:4)

如果您创建方法async,那么您将收到所需的警告,此代码会发出警告:

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

由于非异步方法编译器中的await无法对awaiting发出警告,因为如果不制作方法await,则无法async所以编译器不能建议你非法的东西。

当然,这可能会导致警告试图避免相同的意外行为。编译器可以先说出你的方法async然后await这个调用,但那会是太多的建议。

答案 1 :(得分:1)

Selman22的答案是正确的,我会给他答案,但我想重新写一遍,因为我不明白他的意思:

我错误地认为async / await模型强制执行以下规则:返回任务的任何方法都会抛出编译器警告,表示不等待它。但是,如果我调用以下函数:

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

编译器没有给我们这样的警告。这是有道理的,因为除了新的async / await语法之外的目的存在任务。我们被允许拥有不符合async / await模式的任务。