pub struct Sender<T> { /* 私有字段 */ }展开描述
向关联的 Receiver 发送一个值。
一对 Sender 和 Receiver 由 channel 函数创建。
§示例
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 在未发送的情况下被 drop,则 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"),
}要在析构函数中使用 Sender,请将其放入 Option 中并调用 Option::take。
use tokio::sync::oneshot;
struct SendOnDrop {
sender: Option<oneshot::Sender<&'static str>>,
}
impl Drop for SendOnDrop {
fn drop(&mut self) {
if let Some(sender) = self.sender.take() {
// Using `let _ =` to ignore send errors.
let _ = sender.send("I got dropped!");
}
}
}
let (send, recv) = oneshot::channel();
let send_on_drop = SendOnDrop { sender: Some(send) };
drop(send_on_drop);
assert_eq!(recv.await, Ok("I got dropped!"));实现§
源代码§impl<T> Sender<T>
impl<T> Sender<T>
源代码pub fn send(self, t: T) -> Result<(), T>
pub fn send(self, t: T) -> Result<(), T>
尝试在此 channel 上发送一个值,如果无法发送则将其返回。
此方法会消费 self,因为 oneshot channel 上只能发送一个值。它未标记为 async,因为向 oneshot channel 发送消息永远不需要任何形式的等待。因此,send 方法可以在同步和异步代码中使用而不会出现问题。
当确定 channel 的另一端尚未挂起时,发送成功。发送失败是指相应的接收器已被释放。请注意,返回值 Err 意味着数据将永远不会被接收,但返回值 Ok 并不意味着数据将被接收。相应的接收器可能会在此函数返回 Ok 后立即挂起。
§示例
将值发送到另一个任务
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"),
}源代码pub async fn closed(&mut self)
pub async fn closed(&mut self)
等待关联的 Receiver 句柄关闭。
通过显式调用 close 或 drop Receiver 值来关闭 Receiver。
当与 select! 配合使用时,此函数很有用,可在接收器不再对结果感兴趣时中止计算。
§返回值
返回一个必须被 await 的 Future。
§示例
基本用法
use tokio::sync::oneshot;
let (mut tx, rx) = oneshot::channel::<()>();
tokio::spawn(async move {
drop(rx);
});
tx.closed().await;
println!("the receiver dropped");与 select 配合使用
use tokio::sync::oneshot;
use tokio::time::{self, Duration};
async fn compute() -> String {
// Complex computation returning a `String`
}
let (mut tx, rx) = oneshot::channel();
tokio::spawn(async move {
tokio::select! {
_ = tx.closed() => {
// The receiver dropped, no need to do any further work
}
value = compute() => {
// The send can fail if the channel was closed at the exact same
// time as when compute() finished, so just ignore the failure.
let _ = tx.send(value);
}
}
});
// Wait for up to 10 seconds
let _ = time::timeout(Duration::from_secs(10), rx).await;源代码pub fn poll_closed(&mut self, cx: &mut Context<'_>) -> Poll<()>
pub fn poll_closed(&mut self, cx: &mut Context<'_>) -> Poll<()>
检查 oneshot channel 是否已关闭,如果没有关闭,则在提供的 Context 中调度 Waker,以在 channel 关闭时接收通知。
通过显式调用 close 或当 Receiver 值被 drop 时,Receiver 关闭。
请注意,在多次调用 poll 时,只有传递给最近一次调用的 Context 中的 Waker 才会被调度接收唤醒。
§返回值
此函数返回:
Poll::Pendingif the channel is still open.Poll::Ready(())if the channel is closed.
§示例
use tokio::sync::oneshot;
use std::future::poll_fn;
let (mut tx, mut rx) = oneshot::channel::<()>();
tokio::spawn(async move {
rx.close();
});
poll_fn(|cx| tx.poll_closed(cx)).await;
println!("the receiver dropped");