我试图找到一种简单的方法来实现未来包装箱{0.2}的Future
特性:
extern crate futures;
use futures::executor::ThreadPool;
use futures::prelude::*;
use futures::task::Context;
use std::{thread, time::Duration};
struct SendThree {
firstTime: bool,
}
impl Future for SendThree {
type Item = u32;
type Error = Never;
fn poll(&mut self, ctx: &mut Context) -> Result<Async<Self::Item>, Never> {
if self.firstTime {
self.firstTime = false;
thread::spawn(move || {
thread::sleep(Duration::from_millis(10));
ctx.waker().wake();
});
Ok(Async::Pending)
} else {
Ok(Async::Ready(3))
}
}
}
fn main() {
let mut fut = SendThree { firstTime: true };
let mut executor: ThreadPool = ThreadPool::new().unwrap();
let result = executor.run(fut).unwrap();
println!("{}", result);
}
我的问题是Context
变量不是Send
所以我无法从另一个帖子调用wake
:
error[E0277]: the trait bound `futures::executor::Executor: std::marker::Send` is not satisfied
--> src/main.rs:19:13
|
19 | thread::spawn(move || {
| ^^^^^^^^^^^^^ `futures::executor::Executor` cannot be sent between threads safely
|
= help: the trait `std::marker::Send` is not implemented for `futures::executor::Executor`
= note: required because of the requirements on the impl of `std::marker::Send` for `&mut futures::executor::Executor`
= note: required because it appears within the type `std::option::Option<&mut futures::executor::Executor>`
= note: required because it appears within the type `futures::task::Context<'_>`
= note: required because of the requirements on the impl of `std::marker::Send` for `&mut futures::task::Context<'_>`
= note: required because it appears within the type `[closure@src/main.rs:19:27: 22:14 ctx:&mut futures::task::Context<'_>]`
= note: required by `std::thread::spawn`
如果我将代码更改为此可行,但我无法阻止thread::sleep
:
if self.firstTime {
self.firstTime = false;
ctx.waker().wake();
Ok(Async::Pending)
}
有没有惯用的方法来实现这个?
答案 0 :(得分:0)
虽然Context
无法跨线程发送,但Waker
是:
fn poll(&mut self, ctx: &mut Context) -> Result<Async<Self::Item>, Never> {
if self.first_time {
self.first_time = false;
let waker = ctx.waker().clone();
thread::spawn(move || {
thread::sleep(Duration::from_millis(10));
waker.wake();
});
Ok(Async::Pending)
} else {
Ok(Async::Ready(3))
}
}
请注意,这是一种实现超时的非常低效的方法。应该使用Futures-native方法。