【发布时间】: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异步并在awaitingDoStartProcessingAsync()内部,我感到很惊讶。你为什么不直接删除那些特定的关键字然后做var result = x.StartAsync()它应该可以工作 -
@TomTom 仅仅存在
async关键字不会自动使方法异步。需要有一个await关键字,并且您正在等待的方法也应该是异步的。如果您在方法中有耗时的部分,请考虑在另一个线程中调用它,即await Task.Run(()=> DoStartProcessingAsync());
标签: c# async-await