pub struct Receiver<T> { /* private fields */ }展开描述
从关联的 Sender 接收一个值。
一对
Sender
和
Receiver
由
channel
函数
创建。
此通道
没有 recv 方法,
因为
receiver 本身
实现了
Future
trait。
要接收
Result<T, error::RecvError>,
直接
对
Receiver
对象
使用
.await。
Future
trait 上的 poll 方法
允许
虚假地返回
Poll::Pending,
即使
消息已经被
发送。
如果
发生
此类虚假失败,
则
调用者
将在
虚假失败
解决
后被唤醒,
以便
调用者
可以
再次尝试
接收
消息。
请注意,
收到
此类唤醒
并不
保证
下一次调用
会成功
—
它可能
以
另一个
虚假失败
而失败。
(虚假失败
并不意味着
消息丢失,
只是
被延迟了。)
§Cancellation safety
Receiver
是 cancel safe 的。
如果
将其用作
tokio::select!
语句中
的
nevent,
且其他
分支
先完成,
则
可以
保证
此通道
没有
收到任何
消息。
§示例
use tokio::sync::oneshot;
let (tx, rx) = oneshot::channel();
tokio::spawn(async move {
if let Err(_) = tx.send(3) {
println!("the receiver dropped");
}
});
match rx.await {
Ok(v) => println!("got = {:?}", v),
Err(_) => println!("the sender dropped"),
}如果 sender
在
未发送的情况下
被丢弃,
receiver
将
失败并返回
error::RecvError:
use tokio::sync::oneshot;
let (tx, rx) = oneshot::channel::<u32>();
tokio::spawn(async move {
drop(tx);
});
match rx.await {
Ok(_) => panic!("This doesn't happen"),
Err(_) => println!("the sender dropped"),
}要在 tokio::select! 循环
中使用
Receiver,
在
通道前
加上
&mut。
use tokio::sync::oneshot;
use tokio::time::{interval, sleep, Duration};
let (send, mut recv) = oneshot::channel();
let mut interval = interval(Duration::from_millis(100));
tokio::spawn(async move {
sleep(Duration::from_secs(1)).await;
send.send("shut down").unwrap();
});
loop {
tokio::select! {
_ = interval.tick() => println!("Another 100ms"),
msg = &mut recv => {
println!("Got message: {}", msg.unwrap());
break;
}
}
}实现§
Source§impl<T> Receiver<T>
impl<T> Receiver<T>
Sourcepub fn close(&mut self)
pub fn close(&mut self)
阻止关联的 Sender 句柄发送值。
保证在调用 close 之后发生的任何 send 操作都会失败。调用 close 后,如果一个值是在 close 调用完成之前发送的,应调用 try_recv 来接收该值。
此函数用于执行优雅关闭,并确保不会有值被发送到通道而永远不会被接收。
如果消息已接收或通道已关闭,则 close 是空操作。
§示例
阻止值被发送
use tokio::sync::oneshot;
use tokio::sync::oneshot::error::TryRecvError;
let (tx, mut rx) = oneshot::channel();
assert!(!tx.is_closed());
rx.close();
assert!(tx.is_closed());
assert!(tx.send("never received").is_err());
match rx.try_recv() {
Err(TryRecvError::Closed) => {}
_ => unreachable!(),
}接收在调用 close 之前发送的值
use tokio::sync::oneshot;
let (tx, mut rx) = oneshot::channel();
assert!(tx.send("will receive").is_ok());
rx.close();
let msg = rx.try_recv().unwrap();
assert_eq!(msg, "will receive");Sourcepub fn is_terminated(&self) -> bool
pub fn is_terminated(&self) -> bool
检查此接收者是否已终止。
如果此接收者已经产生了 Poll::Ready 结果,此函数返回 true。如果是这样,则不应再 poll 此接收者。
§示例
发送一个值并 poll 它。
use tokio::sync::oneshot;
use std::task::Poll;
let (tx, mut rx) = oneshot::channel();
// A receiver is not terminated when it is initialized.
assert!(!rx.is_terminated());
// A receiver is not terminated it is polled and is still pending.
let poll = futures::poll!(&mut rx);
assert_eq!(poll, Poll::Pending);
assert!(!rx.is_terminated());
// A receiver is not terminated if a value has been sent, but not yet read.
tx.send(0).unwrap();
assert!(!rx.is_terminated());
// A receiver *is* terminated after it has been polled and yielded a value.
assert_eq!((&mut rx).await, Ok(0));
assert!(rx.is_terminated());丢弃 sender。
use tokio::sync::oneshot;
let (tx, mut rx) = oneshot::channel::<()>();
// A receiver is not immediately terminated when the sender is dropped.
drop(tx);
assert!(!rx.is_terminated());
// A receiver *is* terminated after it has been polled and yielded an error.
let _ = (&mut rx).await.unwrap_err();
assert!(rx.is_terminated());Sourcepub fn is_empty(&self) -> bool
pub fn is_empty(&self) -> bool
检查通道是否为空。
如果通道没有消息,此方法返回 true。
poll 空的接收者(可能已经产生了一个值)不一定安全。请改用 is_terminated() 来检查接收者是否可以安全地被 poll。
§示例
发送一个值。
use tokio::sync::oneshot;
let (tx, mut rx) = oneshot::channel();
assert!(rx.is_empty());
tx.send(0).unwrap();
assert!(!rx.is_empty());
let _ = (&mut rx).await;
assert!(rx.is_empty());丢弃 sender。
use tokio::sync::oneshot;
let (tx, mut rx) = oneshot::channel::<()>();
// A channel is empty if the sender is dropped.
drop(tx);
assert!(rx.is_empty());
// A closed channel still yields an error, however.
(&mut rx).await.expect_err("should yield an error");
assert!(rx.is_empty());已终止的通道是空的。
use tokio::sync::oneshot;
#[tokio::main]
async fn main() {
let (tx, mut rx) = oneshot::channel();
tx.send(0).unwrap();
let _ = (&mut rx).await;
// NB: an empty channel is not necessarily safe to poll!
assert!(rx.is_empty());
let _ = (&mut rx).await;
}Sourcepub fn try_recv(&mut self) -> Result<T, TryRecvError>
pub fn try_recv(&mut self) -> Result<T, TryRecvError>
尝试接收一个值。
如果通道中存在待处理的值,则返回它。如果没有发送值,则当前任务不会被注册以接收未来的通知。
此函数用于在异步任务上下文之外调用。
请注意,与 poll 方法不同,try_recv 方法不会虚假地失败。在此次 try_recv 调用之前发生的任何 send 或 close 事件都将正确返回给调用者。
§Return
Ok(T)if a value is pending in the channel.Err(TryRecvError::Empty)if no value has been sent yet.Err(TryRecvError::Closed)if the sender has dropped without sending a value, or if the message has already been received.
§示例
在值发送之前调用 try_recv,然后在之后调用。
use tokio::sync::oneshot;
use tokio::sync::oneshot::error::TryRecvError;
let (tx, mut rx) = oneshot::channel();
match rx.try_recv() {
// The channel is currently empty
Err(TryRecvError::Empty) => {}
_ => unreachable!(),
}
// Send a value
tx.send("hello").unwrap();
match rx.try_recv() {
Ok(value) => assert_eq!(value, "hello"),
_ => unreachable!(),
}当 sender 在发送值之前已丢弃时调用 try_recv
use tokio::sync::oneshot;
use tokio::sync::oneshot::error::TryRecvError;
let (tx, mut rx) = oneshot::channel::<()>();
drop(tx);
match rx.try_recv() {
// The channel will never receive a value.
Err(TryRecvError::Closed) => {}
_ => unreachable!(),
}Sourcepub fn blocking_recv(self) -> Result<T, RecvError>
pub fn blocking_recv(self) -> Result<T, RecvError>
在异步上下文之外调用的阻塞接收。
§Panics
如果在异步执行上下文中调用此函数会触发 panic。
§示例
use std::thread;
use tokio::sync::oneshot;
#[tokio::main]
async fn main() {
let (tx, rx) = oneshot::channel::<u8>();
let sync_code = thread::spawn(move || {
assert_eq!(Ok(10), rx.blocking_recv());
});
let _ = tx.send(10);
sync_code.join().unwrap();
}