AsyncReadExt::read_u64函数并不直接支持取消操作,但可以通过使用tokio::select!宏和一个额外的取消通道来实现取消。具体的实现方法如下:
use tokio::io::AsyncReadExt;
use tokio::sync::mpsc::{channel, Sender};
use std::io::Error;
async fn read_with_cancel(mut reader: R, cancel: Sender<()>) -> Result
where
R: AsyncReadExt + Unpin,
{
let mut buf = [0; 8];
let mut n = 0usize;
tokio::select! {
res = reader.read(&mut buf) => {
let mut bytes_read = res?;
n += bytes_read;
while bytes_read > 0 && n < 8 {
bytes_read = reader.read(&mut buf[n..]).await?;
n += bytes_read;
}
}
_ = cancel.recv() => {
return Err(Error::new(std::io::ErrorKind::Interrupted, "cancelled"));
}
}
Ok(u64::from_be_bytes(buf))
}
这个函数将读取操作包含在了tokio::select!宏中,并在取消通道上等待。如果收到了一个取消请求,函数将立即返回带有一个Error的Result。否则,函数将连续尝试读取充分的字节数,之后将这些字节解析成一个u64值并返回。