【问题标题】:When I use await in an async method why does it not skip that so it can work in the background and go to the following lines?当我在异步方法中使用 await 时,为什么它不跳过它,以便它可以在后台工作并转到以下几行?
【发布时间】:2020-02-27 02:05:21
【问题描述】:

我有以下代码:

protected override async void OnStart() {
   await Helper.PopulateMetrics();
   await Helper.LogStart();
   if (Settings.Rev == REV.No && (new[] { 15, 30, 50 }).Contains(Settings.Trk2))

我想我很困惑,因为当我在 await Helper.LogStart() 中设置断点时,我在以“if (Settings ...”开头的行之前看到了他的断点

因为有await,后面的代码应该不会先被命中?

LogStart() 方法如下所示:

 public static async Task LogStart()
 {
     // code
     await App.CDB.InsertLogItem(logStart);
 }

理想情况下,我希望这两种方法一个接一个地在后台运行,而代码立即跳过它们。

【问题讨论】:

  • 好吧,因为你是专门 await ing 它,在它完成之前什么都不会继续。
  • 你似乎完全误解了await 是什么。 await 之后的行将在等待的事情完成后运行。
  • 不,在继续之前,您正在awaiting 调用结果。如果您省略了await,那么if 可能会在await App.CDB.InsertLogItem(logStart); 之前执行
  • 这能回答你的问题吗? How does await async work in C#
  • 附注avoid async void

标签: c# async-await


【解决方案1】:

await 关键字导致执行等到Helper.LogStart() 函数完成。如果要继续执行,可以将返回的Task对象存入另一个变量,稍后再将await放在上面:

var task = Helper.LogStart();
/* something else */
await task;

【讨论】:

  • 我想要的是跳过冗长的后台作业并尽快完成onStart。你能举个例子说明我是怎么做到的吗?
  • 您是否需要跟踪后台作业,还是使用“即发即弃”方法就足够了?在这种情况下,您可能完全跳过await。但是,我建议至少指定一个.ContinueWith(),以防发生异常。
  • @Alan2 OnStart 确实会在您点击await 后立即返回。但是当任务完成时,你有点“回到”OnStart。我看到你对 JavaScript 很熟悉,所以也许我应该用 Promise 来解释一下:await 之后的行基本上是 Promise 的 then 部分。
  • 其他两个任务一劳永逸。但我也很想知道如何实现 .ContinueWith()。
  • @Alan2 Async/await 并不意味着是一劳永逸的事情。根据您正在使用的应用程序的类型,还有其他方法可以安排后台工作以一劳永逸的方式完成。
【解决方案2】:

当我们使用 await 时,并不意味着它会跳过该代码并在后台运行。当我们在那个地方有 await 时,将创建新的子线程,并且该新线程将处理 PopularMatrics() 的执行,但主线程将等待子线程完成其工作。

【讨论】:

  • Async-await 与线程无关。它只是告诉等待的方法完成后将继续执行。
  • 线程在任务运行时不会阻塞。 await 关键字提供了一种非阻塞方式来启动任务,然后在该任务完成后继续执行。
  • 正确,它不会阻塞当前线程,同时释放它以做其他事情,但它不会创建一个新线程来运行等待的方法(不是必需的)。这只意味着它将在“一段时间后”运行,如何以及何时仅取决于方法的实现方式。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-01-12
  • 1970-01-01
  • 1970-01-01
  • 2017-08-19
  • 1970-01-01
  • 1970-01-01
  • 2019-11-20
相关资源
最近更新 更多