如何在不阻塞的情况下偷看频道并且仍然能够检测到挂断?
How to peek on channels without blocking and still being able to detect hangup?
根据 Rust Receiver
结尾的 .try_iter() 方法的文档 std::mpsc::channel
,我知道这个迭代器要么产生 "None":
- 当通道没有数据时
- 或者当频道的另一端挂断时。
在我的例子中,我想peek
进入频道,不阻塞,从而确定是否:
- 有数据(但没有消耗它),或
- 没有数据,或者
- 频道已挂断
问题是如果我..
match my_receiver.try_iter().peekable().peek() {
Some(data) => {/* there is data */}
None => {/* there is no data, but there may be later.. or maybe not, because the channel has maybe hung up, I can't tell! */}
}
..我只能区分两种情况。
我如何才能窥视通道的 receiver
端并区分这三种可能的结果,而不会在有数据时阻止或消耗数据?
你可以使用 try_recv 做你想做的事。
它returns一个Result<T, TryRecvError>
和TryRecvError
可以是Empty
或Disconnected
。
match my_receiver.try_recv() {
Ok(data) => {/* handle data */}
Err(TryRecvError::Disconnected) => {/* handle sender disconnected */}
Err(TryRecvError::Empty) => {/* handle no data available yet */}
}
try_iter()
方法 return 是一个丢弃 Error
值的迭代器,因此您无法区分大小写。
您可以创建自己的迭代器来迭代 Result
而不是丢弃错误值:
pub struct TryIterResult<'a, T: 'a> {
rx: &'a Receiver<T>,
}
pub fn try_iter_result<'a, T>(rx: &'a Receiver<T>) -> TryIterResult<'a, T> {
TryIterResult { rx: &rx }
}
impl<'a, T> Iterator for TryIterResult<'a, T> {
type Item = Result<T, TryRecvError>;
fn next(&mut self) -> Option<Result<T, TryRecvError>> {
match self.rx.try_recv() {
Ok(data) => Some(Ok(data)),
Err(TryRecvError::Empty) => Some(Err(TryRecvError::Empty)),
Err(TryRecvError::Disconnected) => None
}
}
}
然后您将能够获得一个可窥视的迭代器,它将 return 三个可能的条件:
match try_iter_result(my_receiver).peekable().peek() {
Some(Ok(data)) =>{ /* there is data */},
Some(Err(_)) => { /* nothing available right now */ },
None => {/* disconnected */}
}
根据 Rust Receiver
结尾的 .try_iter() 方法的文档 std::mpsc::channel
,我知道这个迭代器要么产生 "None":
- 当通道没有数据时
- 或者当频道的另一端挂断时。
在我的例子中,我想peek
进入频道,不阻塞,从而确定是否:
- 有数据(但没有消耗它),或
- 没有数据,或者
- 频道已挂断
问题是如果我..
match my_receiver.try_iter().peekable().peek() {
Some(data) => {/* there is data */}
None => {/* there is no data, but there may be later.. or maybe not, because the channel has maybe hung up, I can't tell! */}
}
..我只能区分两种情况。
我如何才能窥视通道的 receiver
端并区分这三种可能的结果,而不会在有数据时阻止或消耗数据?
你可以使用 try_recv 做你想做的事。
它returns一个Result<T, TryRecvError>
和TryRecvError
可以是Empty
或Disconnected
。
match my_receiver.try_recv() {
Ok(data) => {/* handle data */}
Err(TryRecvError::Disconnected) => {/* handle sender disconnected */}
Err(TryRecvError::Empty) => {/* handle no data available yet */}
}
try_iter()
方法 return 是一个丢弃 Error
值的迭代器,因此您无法区分大小写。
您可以创建自己的迭代器来迭代 Result
而不是丢弃错误值:
pub struct TryIterResult<'a, T: 'a> {
rx: &'a Receiver<T>,
}
pub fn try_iter_result<'a, T>(rx: &'a Receiver<T>) -> TryIterResult<'a, T> {
TryIterResult { rx: &rx }
}
impl<'a, T> Iterator for TryIterResult<'a, T> {
type Item = Result<T, TryRecvError>;
fn next(&mut self) -> Option<Result<T, TryRecvError>> {
match self.rx.try_recv() {
Ok(data) => Some(Ok(data)),
Err(TryRecvError::Empty) => Some(Err(TryRecvError::Empty)),
Err(TryRecvError::Disconnected) => None
}
}
}
然后您将能够获得一个可窥视的迭代器,它将 return 三个可能的条件:
match try_iter_result(my_receiver).peekable().peek() {
Some(Ok(data)) =>{ /* there is data */},
Some(Err(_)) => { /* nothing available right now */ },
None => {/* disconnected */}
}