是否可以声明异步方法为返回void以使CS4014警告静音?

Zun*_*Tzu 9 c# async-await

Visual Studio会对此代码发出警告('因为不等待此调用,在调用完成之前会继续执行当前方法').

static void Main(string[] args)
{
    FireAndForget(); // <-- Warning CS4014
    // Do something else.
}

static async Task FireAndForget()
{
    // Do something (cannot throw).
}
Run Code Online (Sandbox Code Playgroud)

我的理解是,在这种特殊情况下不等待任务是可以的,因为FireAndForget永远不会抛出异常.

我没有考虑使用pragma禁用警告,而是考虑将FireAndForget的返回类型从Task更改为void.这有效地使编译器沉默.

static async void FireAndForget() // <-- Task changed to void
{
    // Do something (cannot throw).
}
Run Code Online (Sandbox Code Playgroud)

然而,根据Stephen Cleary的说法,应该避免使用'async void'方法,因此我不太清楚该怎么做.

如果方法不是设计为首先等待并且没有抛出异常,那么是否可以使用'async void'方法?

Ste*_*ary 11

这是极为罕见的具有真正的发射后不管操作; 也就是说,一个操作:

  • 完成后无人关心.
  • 没有人关心它是否完成.
  • 没有人关心它是否会引发异常.

特别是最后一个; 大多数所谓的"即发即忘"操作实际上并不是"一劳永逸",因为如果不成功就需要采取一些行动.

也就是说,在某些情况下,真正的"即发即弃"是适用的.

我更喜欢async Task通过将任务分配给其他未使用的变量来使用并避免编译器警告:

var _ = FireAndForget();
Run Code Online (Sandbox Code Playgroud)

async Task方法比async void方法更可重用和可测试.

但是,如果我的团队中的开发人员只是使用了,我就不会赞成async void.

  • @ZunTzu不,他们不是那个意思.从同步方法*调用异步方法通常是错误的*.解决方案通常不是解雇和忘记,而是首先不做.至于你的第一个评论中的问题,在大多数异步程序中,你将在所有异步的顶级程序中有一个消息循环(或一些类似的概念),它处理发布的消息,然后继续触发其他异步操作. (2认同)