这个异步方法缺少'await'运算符,将会同步运行。

22

我的程序有以下语句的3个警告:

此异步方法缺少 'await' 操作符,将以同步方式运行。 考虑使用 'await' 运算符等待非阻塞 API 调用, 或使用 'await Task.Run(...)' 在后台线程上进行 CPU 绑定工作。

这个警告是什么意思?我该怎么办?

这是我的代码:它是否使用多线程运行?

static void Main(string[] args)
{
    Task task1 = new Task(Work1);
    Task task2 = new Task(Work2);
    Task task3 = new Task(Work3);

    task1.Start();
    task2.Start();
    task3.Start();

    Console.ReadKey();
}

static async void Work1()
{
    Console.WriteLine("10 started");
    Thread.Sleep(10000);
    Console.WriteLine("10 completed");
}

static async void Work2()
{
    Console.WriteLine("3 started");
    Thread.Sleep(3000);
    Console.WriteLine("3 completed");
}

static async void Work3()
{
    Console.WriteLine("5 started");
    Thread.Sleep(5000);
    Console.WriteLine("5 completed");
}

3
async并不意味着“多线程”。请参阅我的有关async的介绍文章,了解async的作用。不要改变原意,使内容更通俗易懂。文章链接:http://blog.stephencleary.com/2012/02/async-and-await.html - Stephen Cleary
@StephenCleary 谢谢,这篇文章非常好,易于理解。 - mjb
5个回答

11

async 关键字本身并没有什么实际作用。如果从你的代码中删除它,你的代码将完全按照原样运行。

async 关键字有什么作用呢?

  • 它改变了方法内部的有效性,具体来说,它允许你使用 await 关键字。
  • 因此,这意味着方法的主体会根据方法主体中存在的 await 进行转换。
  • 如果该方法返回一个值,那么该方法也会被转换为将返回值包装在一个 Task 中。

然而,如果 a) 你的方法主体中没有任何 await,且 b) 返回类型为 void,则不会实现任何特殊功能。编译器警告会试图清楚地说明这一点-没有任何 awaitasync 方法就没有任何意义。 await 是这个特性的更重要的部分。


1
如果只有异步方法体内的方法是可等待的,而且这个异步方法在其他地方也被使用了await,那么怎么办呢?创建一个带有继续操作的第二个方法并将异步方法包装在其中可能更好一些。 - Ostati

9
如果要用同步方法覆盖异步方法,您可以:
await Task.Run(() => [YOUR SYNC METHOD]);

5
你在方法中使用了 "async" 关键词,表示 Work1()、Work2() 和 Work3() 方法是异步执行的,但你没有使用 "await" 关键词。因此它以同步方式执行。如果你想要异步执行,请使用 "await" 关键词。
 static async void Work1()
 {
     Console.WriteLine("10 started");
     await Task.Delay(10000);
     Console.WriteLine("10 completed");
 }

 static async void Work2()
 {
     Console.WriteLine("3 started");
     await Task.Delay(3000);
     Console.WriteLine("3 completed");
 }

 static async void Work3()
 {
     Console.WriteLine("5 started");
     await Task.Delay(5000);
     Console.WriteLine("5 completed");
 }

这段代码将异步运行,但不等待结果。 - MistyK

3

是的,你的代码可能会使用多线程。然而,如果你只是移除async关键字,它仍然会这样做。由于你没有解释为什么要用它,我建议将其移除。

如果你想要一个async/await模式,你可以使用Task.Delay(),但我建议在使用之前阅读更多关于async/await的内容:

static async void Work3()
{
    Console.WriteLine("5 started");
    await Task.Delay(5000);
    Console.WriteLine("5 completed");
}

0

你使用了关键字async来指定你的方法(Work1、Work2、Work3),但是在这些方法中没有使用await运算符来调用异步调用。


这段代码将异步运行,但不等待结果。 - MistyK

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接