使用Task.Wait而不是等待异步编程

时间:2018-12-06 14:51:07

标签: c# .net asynchronous async-await task

.Net article on Tasks显示以下两个两个代码段,一个使用await,另一个使用Task.Wait,并说两者在功能上是等效的。

那在技术上不是正确的吗?有人可以澄清一下吗?

如果任务被认为是异步的并且构成了异步编程(TPL)的基础,那么ASP.Net为什么仍要允许对它们进行同步Wait?那样违反他们的主要用途吗?

using System;
using System.Threading.Tasks;

public class Example
{
   public static async Task Main()
   {
      await Task.Run( () => {
                                  // Just loop.
                                  int ctr = 0;
                                  for (ctr = 0; ctr <= 1000000; ctr++)
                                  {}
                                  Console.WriteLine("Finished {0} loop iterations",
                                                    ctr);
                               } );
   }
}
// The example displays the following output:
//        Finished 1000001 loop iterations
using System;
using System.Threading.Tasks;

public class Example
{
   public static void Main()
   {
      Task t = Task.Factory.StartNew( () => {
                                  // Just loop.
                                  int ctr = 0;
                                  for (ctr = 0; ctr <= 1000000; ctr++)
                                  {}
                                  Console.WriteLine("Finished {0} loop iterations",
                                                    ctr);
                               } );
      t.Wait();
   }
}
// The example displays the following output:
//        Finished 1000001 loop iterations

本文应该清楚地说明两个调用之间的区别。

1 个答案:

答案 0 :(得分:4)

  

那么,从技术上讲那不是吗?

否,因为它是非常特定的。并不是说编写等待任务的async方法与同步等待该任务总是相同的,只是非常具体地指的是 async Main方法的名称作为应用程序的入口点。当您使用Main方法async时,它仅同步等待返回的任务,使其在功能上等效于仅同步等待方法内部的任务,而不是使方法async < em>仅在一种确切情况下。

(您还可以提出一个论点,那就是说具有提供的参数的StartNewRun是等效的,并不打算引用异步方法之间的区别。而不是同步等待。)

  

为什么ASP.Net仍然允许同步等待它们?

Task并不是专门用来表示异步完成的工作。它旨在实现以及以使用多个线程并行并行工作。当您使用异步任务时,基本上应该永远不要使用Wait或其他同步阻塞机制,但是如果您使用它来同步执行多线程工作,则很有用。您可以提出[良好]的论点,认为他们应该将这些概念分开,但事实并非如此,现在更改它为时已晚。

  

那不是违反他们的主要实用工具吗?

是的,是的。这就是为什么我不喜欢这种实现的原因,并且希望他们以不同的方式实现它。但是他们没有。

  

本文应该清楚地说明两个调用之间的区别。

是的。