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

时间:2016-09-21 17:04:35

标签: c# async-await

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

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

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

由于

3 个答案:

答案 0 :(得分:16)

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

async () => { await SomeClass.Initiate(new Configuration()); }

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

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

Task.Run在线程池线程上执行其代码。因此,async lambda将在线程池线程上运行。 Task.Run返回Task,表示async lambda的执行。致电Task.Run后,代码会调用Task.Wait

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

这将阻止主控制台应用程序,直到async lambda完全完成。

如果您想了解它是如何进一步分解的,以下内容大致相同:

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

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

答案 1 :(得分:4)

我写了一些.NET Fiddle,只是简单地添加了一些Console.WriteLine调用,希望有助于向您显示执行顺序。

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

  

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

所有异步代码都应返回等待,除非在极少数情况下您正在创作需要启动某些异步调用的事件处理程序。

Task调用返回的Task.Run会立即调用.Wait()

  

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

不需要调用Task.Run,您只需调用从.Wait()方法返回的Task上的SomeClass.Initiate

对于无限循环,控制台应用程序立即退出 - 您可以简单地执行Console.ReadLine并等待用户点击 Enter 键。

答案 2 :(得分:1)

很可能SomeClass.Initiate是无条件标记为async的同步方法。比有人试图让它真正异步运行并添加Task.Run以在单独的线程上运行它。但由于它是控制台应用程序 - 添加.Wait()以等待操作完成。

并且while (true) ;存在,因为在VS控制台应用程序中运行时完成时没有跟踪关闭,更明显的方式 - 添加Console.ReadLine()调用。 while(true)根本不涉及异步部分,因为代码在操作完成之前不会调用.Wait()

另一种可能性是作者正在尝试使用async并且没有.Wait().Result - 因此while(true)会让操作完成。

请参阅async at console app in C#?以了解在控制台应用中运行异步代码的正确方法(仅.Wait().Result