是否有办法在rust的异步函数中获取对当前任务上下文的引用?

问题描述 投票:0回答:1

在rust异步函数中,没有任何方法可以访问当前的Context,而无需编写Future的显式实现?

rust async-await
1个回答
0
投票

在实际回答问题之前,记住Context是什么很有用;每当编写依赖外部资源(例如I / O)的Future的实现时,您都不想忙于等待任何事情。结果,您很可能具有Future的实现,将在其中返回Pending,然后将其唤醒。为此存在Context(和Waker)。

但是,这就是它们:低级实施细节。如果您已经在使用Future而不是编写低级实现,则Waker很可能包含在[[somewhere中,但您无法直接访问。

因此,直接泄漏Waker占实施细节泄漏的时间为99.9%,实际上不建议这样做。但是,将Waker用作

bigger

struct的一部分是完全可以的,但这是您需要从头开始实现自己的Future的地方。 没有其他有效的用例,按照常规,您永远不需要直接访问Waker由于操场的局限性,令人遗憾的是我无法向您展示一个生动的例子,说明何时获得此Waker很有用;但是,将来可能会在这种情况下使用这种设置:假设我们正在建造房屋的前门。我们有一个门铃和一扇门,当有人敲门铃时我们希望得到通知。但是,我们不想在门口等候访客。

因此,我们创建了两个对象:FrontDoorDoorbell,并且我们将wire()的选项赋予Doorbell以连接这两个对象。

pub struct FrontDoor { doorbell: Arc<RwLock<Doorbell>> } impl FrontDoor { pub fn new() -> FrontDoor { FrontDoor { doorbell: Arc::new(RwLock::new(Doorbell { waker: None, visitor: false })) } } pub fn wire(&self) -> Arc<RwLock<Doorbell>> { self.doorbell.clone() // We retrieve the bell } } impl Future for FrontDoor { type Output = (); fn poll(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output> { self.doorbell.read().map(|guard| { match guard.visitor { true => Poll::Ready(()), false => Poll::Pending } }).unwrap_or(Poll::Pending) } } pub struct Doorbell { waker: Option<Waker>, pub visitor: bool } impl Doorbell { pub fn ring(&mut self) { self.visitor = true; self.waker.as_ref().map(|waker| waker.wake_by_ref()); } }

我们的FrontDoor实现了Future,这意味着我们可以将其扔给您选择的执行程序; waker包含在Doorbell对象中,它使我们能够“振铃”并唤醒我们的未来。
© www.soinside.com 2019 - 2024. All rights reserved.