【问题标题】:Async method waiting for end?等待结束的异步方法?
【发布时间】:2016-02-09 10:27:10
【问题描述】:

我正在重写我的一些组件管理以使用异步启动方法。可悲的是,它看起来像是对 async 方法的调用,没有 await,仍然等待结果吗?

谁能赐教?

我在打电话:

public async Task StartAsync() {
    await DoStartProcessingAsync();
}

它本身正在调用 protected abstract Task DoStartProcessingAsync(); 的缓慢实现 - 缓慢是因为它完成了一些 EF 调用,然后创建了一个 appdomain 等 - 需要“年龄”。

实际调用的形式是:

x.StartAsync().Forget();

“忘记”是一个虚拟函数,只是为了避免“无等待”警告:

public static void Forget(this Task task) {
}

可悲的是,这个序列 - 正在等待缓慢的 DoStartAsync 方法完成,我认为没有理由这样做。我在 C# 中已经很老了,但对async/await 却很陌生,我的印象是,除非我等待异步任务,否则该方法将完成。因此,我预计对StartAsyc().Forget() 的调用会立即返回。 INSTEAD 堆栈跟踪显示线程一直进入 DoStartProcessingAsync() 方法,而没有发生任何异步处理。

谁能告诉我我的错误?

【问题讨论】:

  • 你能显示DoStartProcessingAsync()吗?只是为了确保它不仅被称为Async,而且真的在等待某些东西而不是同步工作。
  • 我认为这不是关于异步,而是更多关于后台处理......例如,async Task Blah() { await Something(); } 应该与 Something() 相同 - 这不会神奇地让它发生在背景
  • async 方法将同步运行,直到它到达第一个等待。如果没有等待,则完全同步运行。可以发DoStartProcessingAsync的代码吗?
  • 如果您不想等待您正在使您的 StartAsync 异步并在 awaiting DoStartProcessingAsync() 内部,我感到很惊讶。你为什么不直接删除那些特定的关键字然后做var result = x.StartAsync() 它应该可以工作
  • @TomTom 仅仅存在async 关键字不会自动使方法异步。需要有一个await 关键字,并且您正在等待的方法也应该是异步的。如果您在方法中有耗时的部分,请考虑在另一个线程中调用它,即await Task.Run(()=> DoStartProcessingAsync());

标签: c# async-await


【解决方案1】:

您在这里尝试实现的是一种即发即弃的类型机制。所以async/await 并不是你真正想要的。你不想await 任何东西。

These are designed to free up threads for long running processes。现在您使用await 返回Task,然后“忘记”它。 那么为什么要返回 Task 呢?

您为长时间运行的进程释放了线程,但您也在排队一个最终什么都不做的进程(这增加了您可能不需要的开销)。

简单地这样做,可能更有意义:

public void StartAsync() {
    Task.Run(() => DoStartProcessingAsync());
}

要记住的一件事是,您现在使用的是 ThreadPool 线程而不是 UI 线程(取决于实际调用它的内容)。

【讨论】:

  • 我已经重写 Start 以使用 return Task.Run(DoStopProcessingAsync);返回任务 - 这样启动方法可以等待执行完成。现在按预期工作。
  • @Liam:应该使用Task.Run,而不是更危险的Task.Factory.StartNew
  • @StephenCleary Task.run is just a wrapper for the Task.Factory.StartNew with a few switches。我真的不明白为什么这个添加有很多好处?为了完整起见,我会添加它,但它肯定是课程的马匹吗?它也只有 .Net 4.5。
  • @Liam:是的,但那些开关是really, really important to get right。如果你不指定它们,它们就是错误的。
  • 我目前不针对 .Net 4.5,所以我们不使用它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-08
  • 1970-01-01
  • 2013-07-27
相关资源
最近更新 更多