我正在重写我的一些组件管理以使用异步启动方法。可悲的是,看起来只是调用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()
方法,而不会发生任何异步处理。
任何人都可以告诉我我的错误?
答案 0 :(得分:1)
你在这里想要实现的是一种火灾和遗忘型机制。因此async
/ await
并不是您想要的。你不想await
任何东西。
These are designed to free up threads for long running processes。现在您使用Task
返回await
,然后"忘记"它。 那么为什么要归还Task
?
你为长时间运行的进程释放了线程,但你也排队了一个最终什么都不做的进程(这会增加你可能没有的开销)。
简单地说,这可能更有意义:
<击> 撞击>
<击>public void StartAsync() {
Task.Factory.StartNew(() => DoStartProcessingAsync());
}
击> <击> 撞击>
你应该使用(见评论)
public void StartAsync() {
Task.Run(() => DoStartProcessingAsync());
}
如果你想创建一个简单的任务,虽然你失去了一些控制,see here。 仅限.Net 4.5。
要记住的一件事是你现在使用ThreadPool线程而不是UI线程(取决于实际调用它的内容)。