【问题标题】:Why doesn't Task.Factory.StartNew() throw a compiler warning for await?为什么 Task.Factory.StartNew() 不为 await 抛出编译器警告?
【发布时间】:2014-10-07 22:35:22
【问题描述】:

在 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 运算符如何在幕后工作的讨论的方向,我将非常感激。该语法似乎旨在隐藏很多内容,因为我可以编写一个返回 Tasks 的方法,而该方法体在任何时候都不会创建任何这样的东西。

编辑: 其他人似乎认为您不能等待 StartNew 返回的内容。举个例子:

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

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

【问题讨论】:

  • 您在 void 方法中,不希望返回某些内容。这与调用返回bool 的单个方法没有什么不同。编译器没有理由发出警告/错误。
  • @TyCobb,FunctionAsync 和 Task.Factory.StartNew 都将 Task 作为返回类型,而不是 void。唯一返回类型为 void 的函数是 SyncCaller,它在调用 FunctionAsync 时会收到警告,就像我在示例中所做的那样。

标签: c# .net asynchronous


【解决方案1】:

如果你将你的方法设为async,那么你会得到你想要的警告,这段代码给出了警告:

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

由于在非异步方法中不可能await,编译器不会警告你awaiting,因为你不能await而不使你的方法async。所以编译器不能向你推荐一些非法的东西。

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

【讨论】:

  • 感谢您的回答;不幸的是,我对此有所保留。你是对的:一旦我将方法标记为异步,就会出现该错误。我确实了解如何使用 async/await 语法,并且知道使用 await 需要函数签名中的 async 标记。但是,在我的前两个示例函数中,很明显不需要异步函数签名来接收警告。事实上,在我看来,这就是警告的全部意义所在:它警告您正在使用可等待的方法,而无需等待其完成。
  • 你是对的,但编译器不能建议你做一些不可能做的事情。可能会有另一个警告,但你可以向 C# 编译器团队询问他们为什么没有实现它。
【解决方案2】:

Selman22 的答案是正确的,我会奖励他的答案,但我想重写它,因为我没有立即理解他的观点:

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

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

编译器没有给我们这样的警告。这是有道理的,因为任务存在的目的超出了新的 async/await 语法。我们可以有不符合异步/等待模式的任务。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-01-28
    • 2014-09-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-18
    • 1970-01-01
    相关资源
    最近更新 更多