为什么没有等待的异步函数会导致编译器警告?

时间:2013-04-11 03:38:59

标签: async-await c#-5.0

有人能解释为什么要求c#5中的异步函数至少有1个等待吗?我找不到明确的理由/解释。

根据需要,我的意思是编译器在异步函数内部没有任何await调用时发出警告,但不会抛出编译错误。

来自this answer

  

同样,标记为async的方法必须至少有一个await。在await上,运行时将保存当前线程的状态和调用堆栈,进行异步调用,并展开回运行时的消息循环以处理下一条消息并保持应用程序的响应。当异步操作完成时,在下一个调度机会时,用于启动异步操作的调用堆栈将被推回并继续,就像调用是同步的一样。

但是来自msdn:

  

如果方法不包含await表达式或语句,则它将同步执行。编译器警告会提醒您任何不包含等待的异步方法,因为这种情况可能表示错误。

出现什么类型的错误,这是一个编译器警告而不仅仅是推荐用法?

1 个答案:

答案 0 :(得分:6)

MSDN对此警告有一个很好的描述:Compiler Warning (level 1) CS4014。它的好引用将是:

  

在大多数情况下,这种行为并不是您所期望的。

我认为存在此警告的主要原因是async / await并不是很明显,开发人员通常会犯错误,如下所述。

例如,你有一个方法,可以做几秒钟的重做:

public int DoSomething()
{
    int sum = 0;

    for (int i = 0; i < 10; i++)
    {
        sum += i;
        Thread.Sleep(1000);
    }

    return sum;
}

你在某个地方听说过asyncawait,你想尝试一下。这就是人们常常认为他们会将所有内容都移到后台(可能不常见,但我认为这是它在我阅读更多文档之前的工作方式,所以我们至少可以算一下):

public async Task<int> DoSomething()
{
    int sum = 0;

    for (int i = 0; i < 10; i++)
    {
        sum += i;
        Thread.Sleep(1000);
    }

    return sum;
}

您认为该问题已得到解决,但警告告诉您,如果没有await,则不应使用async,因为它不会执行任何操作,所有代码都将同步运行,最后一个样本使用{{ 1}}类似于下一个代码:

async

在同一个上下文中执行所有操作的地方,调用此方法。

所以这个警告的主要原因我想让人们知道可能他们使用public Task<int> DoSomething() { int sum = 0; for (int i = 0; i < 10; i++) { sum += i; Thread.Sleep(1000); } return Task.Result<int>(sum); } 错了,现在是阅读文档的时候了。