Rust 如何查找tokio::sync::mpsc::Receiver是否已关闭?

Rust 如何查找tokio::sync::mpsc::Receiver是否已关闭?,rust,future,rust-tokio,Rust,Future,Rust Tokio,我有一个循环,在那里我做一些工作,并将结果发送给发送者。这项工作需要时间,如果失败,我需要重试。有可能在我重试时,接收器已关闭,我的重试将是浪费时间。因此,我需要一种方法来检查接收器是否可用,而无需发送消息 在理想情况下,我希望我的代码在伪代码中如下所示: let (tx, rx) = tokio::sync::mpsc::channel(1); tokio::spawn(async move { // do som stuff with rx and drop it after som

我有一个循环,在那里我做一些工作,并将结果发送给发送者。这项工作需要时间,如果失败,我需要重试。有可能在我重试时,接收器已关闭,我的重试将是浪费时间。因此,我需要一种方法来检查接收器是否可用,而无需发送消息

在理想情况下,我希望我的代码在伪代码中如下所示:

let (tx, rx) = tokio::sync::mpsc::channel(1);

tokio::spawn(async move {
   // do som stuff with rx and drop it after some time
    rx.recv(...).await;
});

let mut attempts = 0;
loop {
    if tx.is_closed() {
       break;
    }
    if let Ok(result) = do_work().await {
        attempts = 0;
        let _ = tx.send(result).await;
    } else {
        if attempts >= 10 {
            break;
        } else {
            attempts += 1;
            continue;
        }
    }
};
问题是发送方没有is_closed方法。它有pub fn poll_ready&mut self,cx:&mut Context发送方有一个方法:

尝试立即在此发件人上发送邮件

此方法与发送不同,它在通道缓冲区已满或没有接收器等待获取某些数据时立即返回。与send相比,该功能有两种故障情况,而不是一种断开连接,一种是满缓冲区

使用它而不是发送并检查错误:

如果让ErrTrySendError::Closed_uz=tx.sendresult.await{ 打破 } 可以使用期货板条箱中的poll_fn做您想要做的事情。它使用函数returning Poll来返回未来

使用futures::future::poll\u fn;//0.3.5 使用std::future::future; 使用tokio::sync::mpsc::{channel,error::ClosedError,Sender};//0.2.22 使用tokio::time::delay_;//0.2.22 fn等待_,直到_准备好impl Future+'a{ poll_fnmove | cx | sender.poll_readycx } [tokio::main] 异步fn主{ 让mut tx,mut rx=通道::1; 东京:异步移动{ //接收一个值并关闭通道; 让val=rx.recv.wait; println!{:?},val; }; 等待,直到准备就绪&mut tx.wait.unwrap; tx.send123.wait.unwrap; 等待,直到准备就绪&mut tx.wait.unwrap; 延迟时间::时间::持续时间::从秒开始等待; tx.send456.await.unwrap;//456可能从未打印出来, //尽管有积极的反应 //发送成功了吗 } 然而,请注意,在一般情况下,这容易受到影响。即使发送方的poll_ready在通道中保留了一个插槽供以后使用,也有可能在就绪检查和实际发送之间关闭接收端。我试图在代码中指出这一点。

发件人有一个方法:

尝试立即在此发件人上发送邮件

此方法与发送不同,它在通道缓冲区已满或没有接收器等待获取某些数据时立即返回。与send相比,该功能有两种故障情况,而不是一种断开连接,一种是满缓冲区

使用它而不是发送并检查错误:

如果让ErrTrySendError::Closed_uz=tx.sendresult.await{ 打破 } 可以使用期货板条箱中的poll_fn做您想要做的事情。它使用函数returning Poll来返回未来

使用futures::future::poll\u fn;//0.3.5 使用std::future::future; 使用tokio::sync::mpsc::{channel,error::ClosedError,Sender};//0.2.22 使用tokio::time::delay_;//0.2.22 fn等待_,直到_准备好impl Future+'a{ poll_fnmove | cx | sender.poll_readycx } [tokio::main] 异步fn主{ 让mut tx,mut rx=通道::1; 东京:异步移动{ //接收一个值并关闭通道; 让val=rx.recv.wait; println!{:?},val; }; 等待,直到准备就绪&mut tx.wait.unwrap; tx.send123.wait.unwrap; 等待,直到准备就绪&mut tx.wait.unwrap; 延迟时间::时间::持续时间::从秒开始等待; tx.send456.await.unwrap;//456可能从未打印出来, //尽管有积极的反应 //发送成功了吗 }
然而,请注意,在一般情况下,这容易受到影响。即使发送方的poll_ready在通道中保留了一个插槽供以后使用,也有可能在就绪检查和实际发送之间关闭接收端。我试图在代码中指出这一点。

发送一条接收方忽略的空消息。它可能是任何东西。例如,如果您现在发送T,您可以将其更改为Option,并让接收者忽略Nones


是的,这会管用的,尽管我不太喜欢这种方法,因为我需要改变沟通方式


我不会对沟通方式挂断电话。这不是一个定义良好的网络协议,应该与实现细节隔离;这是您自己的两段代码之间的内部通信机制。

发送一条接收方忽略的空消息。它可能是任何东西。例如,如果您现在发送T,您可以将其更改为Option,并让接收者忽略Nones


是的,这会管用的,尽管我不太喜欢这种方法,因为我需要改变沟通方式

我不会对沟通方式挂断电话。这不是一个定义良好的网络协议
与实施细节隔离;这是您自己的两段代码之间的内部通信机制。

但我没有要发送的值。这就是问题所在。在获取和发送之前,我需要知道是否还需要值。如果我有一个值,我就不会对旧的常规发送方法有问题。我已经使用poll_ready更新了我的答案,并提供了一个可能的解决方案。但是我没有要发送的值。这就是问题所在。在获取和发送之前,我需要知道是否还需要值。如果我有一个值,我就不会对旧的常规发送方法有问题。我已经使用poll_ready更新了我的答案,并提供了一个可能的解决方案。是的,这会起作用,尽管我不太喜欢这种方法,因为我需要更改通信格式。是的,这会起作用,虽然我不太喜欢这种方式,因为我需要改变沟通方式。