了解在一行中使用的Task.Run + Wait()+ async + await的使用

Pdo*_*don 10 c# async-await

我是C#新手,所以我很难理解一些概念,而且我遇到了一段我不太了解的代码:

static void Main(string[] args)
{
 Task.Run(async () => { await SomeClass.Initiate(new Configuration()); }).Wait();
 while (true) ;
}
Run Code Online (Sandbox Code Playgroud)

据我所知,这运行一个启动方法的任务.此方法运行,然后,一旦完成,它将进入无限循环等待.感觉代码没有意义,或者我不理解正确.

谢谢

Ste*_*ary 20

你可以把它分成几个部分:

async () => { await SomeClass.Initiate(new Configuration()); }
Run Code Online (Sandbox Code Playgroud)

是一个lambda表达式,它定义了一个async等待另一个方法的方法.然后将此lambda传递给Task.Run:

Task.Run(async () => { await SomeClass.Initiate(new Configuration()); })
Run Code Online (Sandbox Code Playgroud)

Task.Run在线程池线程上执行其代码.因此,该asynclambda将在线程池线程上运行.Task.Run返回Task表示asynclambda 执行的a .调用后Task.Run,代码调用Task.Wait:

Task.Run(async () => { await SomeClass.Initiate(new Configuration()); }).Wait();
Run Code Online (Sandbox Code Playgroud)

这将阻止主控制台应用程序,直到异步lambda完全完成.

如果你想看看它是如何进一步分解的,下面大致相同:

static async Task AnonymousMethodAsync()
{
  await SomeClass.Initiate(new Configuration());
}

static void Main(string[] args)
{
  var task = Task.Run(() => AnonymousMethodAsync());
  task.Wait();
  while (true) ;
}
Run Code Online (Sandbox Code Playgroud)

  • @TomDane:原始代码试图进行异步同步。虽然sync-over-async 曾经在控制台应用程序的`Main` 方法中很常见,但现在`Main` 可以是`async`,因此不再需要。 (2认同)

Dav*_*ine 6

我写了一个小.NET Fiddle,它只是添加了一些Console.WriteLine调用,希望能帮助您了解执行顺序。

所述Task.Run返回一个Task表示一个异步操作,(即异步运行的方法)。在这种情况下它的参数是Func<Task>. 您的代码使用了asyncandawait关键字,因此您的调用SomeClass.Initiate是异步 lambda。

将指定的工作排入队列以在线程池上运行,并为函数返回的任务返回一个代理。

所有异步代码都应返回一个可等待对象,除非在极少数情况下您正在编写需要启动一些异步调用的事件处理程序。

Task所从调用返回Task.Run时立即调用.Wait()

等待 Task 在指定的时间间隔内完成执行。

这一呼吁Task.Run是不需要的,你可以简单地调用.Wait()Task是从返回的SomeClass.Initiate方法。

至于无限循环,控制台应用程序会立即退出——例如,您可以简单地执行该操作Console.ReadLine并等待用户按下Enter键。