我有一个futures::sync::mpsc::unbounded
频道。我可以将邮件发送到UnboundedSender<T>
,但是从UnboundedReciever<T>
接收邮件时遇到问题。
我使用通道将消息发送到UI线程,并且有一个在每一帧都被调用的函数,并且我想从每一帧的通道中读取所有可用消息,而在没有可用线程时不阻塞线程消息。
从我读到的Future::poll
方法来看,我需要的是一种轮询,如果得到Async :: Ready,则对消息进行某些处理,如果没有,则返回从功能上。
问题是当没有任务上下文时(我不确定这意味着什么或怎么做),poll
会出现恐慌。
我尝试过的事情:
let (sender, receiver) = unbounded(); // somewhere in the code, doesn't matter
// ...
let fut = match receiver.by_ref().collect().poll() {
Async::Ready(items_vec) => // do something on UI with items,
_ => return None
}
这很恐慌,因为我没有任务上下文。
也尝试过:
let (sender, receiver) = unbounded(); // somewhere in the code, doesn't matter
// ...
let fut = receiver.by_ref().collect(); // how do I run the future?
tokio::runtime::current_thread::Runtime::new().unwrap().block_on(fut); // this blocks the thread when there are no items in the receiver
当流中没有任何项目时,我希望在不阻塞线程的情况下阅读UnboundedReceiver<T>
。
谢谢!
答案 0 :(得分:0)
您使用的期货不正确-您需要Runtime
和更多样板才能使它起作用:
extern crate tokio;
extern crate futures;
use tokio::prelude::*;
use futures::future::{lazy, ok};
use futures::sync::mpsc::unbounded;
use tokio::runtime::Runtime;
fn main() {
let (sender, receiver) = unbounded::<i64>();
let receiver = receiver.for_each(|result| {
println!("Got: {}", result);
Ok(())
});
let rt = Runtime::new().unwrap();
rt.executor().spawn(receiver);
let lazy_future = lazy(move || {
sender.unbounded_send(1).unwrap();
sender.unbounded_send(2).unwrap();
sender.unbounded_send(3).unwrap();
ok::<(), ()>(())
});
rt.block_on_all(lazy_future).unwrap();
}
进一步阅读,摘自Tokio's runtime model:
[...]为了使用Tokio并成功执行任务,应用程序必须为该应用程序的任务所依赖的资源启动执行程序和必要的驱动程序。这需要大量的样板。为了管理样板,Tokio提供了几个运行时选项。运行时是与所有必要驱动程序捆绑在一起的执行程序,可以为Tokio的资源提供动力。无需单独管理所有各种Tokio组件,而是可以在单个调用中创建并启动运行时。
Tokio提供了concurrent runtime和single-threaded runtime。并发运行时由多线程,窃取工作的执行程序支持。单线程运行时在当前线程上执行所有任务和驱动程序。用户可以选择具有最适合应用程序特征的运行时。