我希望能够启动一个在后台运行的future,而不是在父函数作用域中立即等待它。
类似于一个动态的join_all
,我可以在一个循环中添加新的期货到一个集合中,然后将集合传递给另一个函数,该函数可以等待整个集合(已经在运行)。
我希望能够做这样的事情:
join_all(vec![
log_arg(&c),
log_arg(&c)
]).await;
但问题是:
.await
启动未来的执行,但也在当前函数等待它。- 如何在不等待的情况下开始执行?
&c
不是'static
- 这似乎是所有时雄API的一个要求,即“启动未来的执行,而不等待当前fn范围内的结果”,例如
spawn_local
- 如果所有的期货都在一根线上,那就没问题了。
2条答案
按热度按时间q3qa4bjr1#
如何在不等待的情况下开始执行?
spawn
任务。这似乎是所有时雄API的一个要求,即“启动未来的执行,而不等待当前fn范围内的结果”,例如
spawn_local
是的,因为你正在生成一个任务,所以这个任务有可能比拥有这个项目的任何东西都存在,从而导致一个悬空引用,这是不允许的。事实上,在使用
spawn_local
时,这几乎是一个保证:它将在同一个线程(/scheduler)上产生一个任务,并且在当前任务退出或终止之前,该任务根本无法运行。另一种方法是使用“范围任务”(不必立即等待,但最终必须加入)。然而,到目前为止,时雄对结构化并发(有作用域的任务)的支持已经胎死腹中。因此Rust编译器无法知道一个任务没有从初始化它的作用域中“逃逸”,因此它必须假设它确实如此,因此任务捕获的任何内容都应该能够超过当前作用域。
pepwfjgg2#
这是wg-async scope proposal,这是tokio scoped tasks issue
当我遇到类似的问题时,我首先研究了async-scoped(crossbeam::scope的异步版本,或rayon::scope)。最后,我决定写一个新的类型,它为每个未来产生一个任务(或者,在我的例子中是
Stream<Item=String>
),当它被删除时,它确保任务完成。这本质上是“范围”思想的穷人实现。我是这样用的
当
log_printer
超出范围时,drop
将被执行。