我正在重写我的一些组件管理以使用异步启动方法 . 可悲的是,它似乎是一个没有 await
的 async
方法的调用,仍在等待结果?
任何人都可以开导我吗?
我打电话给:
public async Task StartAsync() {
await DoStartProcessingAsync();
}
这本身就是调用 protected abstract Task DoStartProcessingAsync();
的缓慢执行 - 慢,因为它会覆盖一些EF调用,然后创建一个appdomain等 - 需要"ages" .
实际调用的形式如下:
x.StartAsync().Forget();
“忘记”是一个虚拟函数,只是为了避免“无等待”警告:
public static void Forget(this Task task) {
}
可悲的是,这个序列 - 正在等待缓慢的 DoStartAsync
方法完成,我认为没有理由 . 我在C#中已经很老了,但对于 async/await
来说还是比较新的,我的印象是,除非我等待异步任务 - 否则该方法将完成 . 因此,我预计 StartAsyc().Forget()
的电话会立即返回 . INSTEAD堆栈跟踪显示线程一直进入 DoStartProcessingAsync()
方法,而不会发生任何异步处理 .
任何人都可以告诉我我的错误?
1 回答
你在这里想要实现的是一种火灾和遗忘型机制 . 所以
async
/await
并不是你想要的 . 你不想await
什么的 .These are designed to free up threads for long running processes . 现在你使用
await
然后"forgetting"返回Task
. So why return the Task at all?你为长时间运行的进程释放了线程,但你也排队了一个最终什么都不做的进程(这会增加你可能没有的开销) .
简单地说,这可能更有意义:
public void StartAsync(){
Task.Factory.StartNew(()=> DoStartProcessingAsync());
}
你应该使用(见评论)
如果你想创建一个简单的任务,虽然你失去了一些控制,see here . This is .Net 4.5 only.
要记住的一件事是你现在使用ThreadPool线程而不是UI线程(取决于实际调用它的内容) .