我尝试在Ubuntu 20.0.4上使用notify-rust库,但是发出的通知有不可预测的超时。另外,如果我发送几个通知,它们之间有短暂的延迟,结果可能会有所不同(有时我看到所有通知,有时只看到其中的几个)。
我应用的变通方法:
- 严重
Urgency
,因此通知将永远显示。 - 在显示下一个通知之前等待某个操作,这样就不会丢失任何通知。
use notify_rust::{Notification, Urgency};
use std::{thread, time};
fn main() {
let summaries = ["one", "two"];
for summary in summaries {
let handle = Notification::new()
.summary(summary)
.urgency(Urgency::Critical)
.show()
.unwrap();
// helps displaying all the notifications
handle.wait_for_action(|_action| ());
// delay might vary
thread::sleep(time::Duration::from_millis(10));
}
}
我还试验了lib的timeout
,但没有得到任何好的结果。wait_for_action
方法的主要问题是,有时在发送通知后屏幕上看不到通知,因此主线程正在等待对该通知的操作,但该操作永远不会发生(没有任何内容可点击)。
我想尝试watchdog
方法:启动一个线程,向其中发送通知处理程序,并在超时后关闭通知:
let handle = Notification::new()
...
let thread_handle = handle.clone();
thread::spawn(move || {
thread::sleep(time::Duration::from_secs(60));
thread_handle.close();
});
handle.wait_for_action(|_action| ());
我不知道该怎么做。我不能同时为线程和wait_for_action
使用handle
,因为线程取得了所有权。克隆不能正常工作,它产生的不是NotificationHandle
,而是Notification
。
有没有办法不深入研究notify-rust
库的内部结构来解决这个问题?
我想我可以使用完全不同的方法来解决这个问题,这种方法不涉及调用阻塞wait_for_action
,但我想知道是否有更优雅的解决方案?
1条答案
按热度按时间vngu2lb81#
我想出了另一个通知和超时的算法:我创建了两个线程,而不是依赖
wait_for_action
来捕获通知关闭事件:wait_for_action
,在完成时通过通道发送消息主线程等待消息并在第一条消息到达时继续。
故意忽略消息发送结果:这些消息中只有一个可以成功发送,然后通道超出范围,另一个发送方收到错误,这没关系。
该解决方案有一个缺点:有可能在超时后,不等待前一个通知关闭,就发送另一个通知,我看到第一个通知关闭后,即使主线程结束,那些通知仍然可以显示,所以它们在通知总线上等待。
我还注意到,为
NotificationHandler
实现的另一种方法可能更适合此任务:on_close,但是它是使用wait_for_action
实现的,所以它也是阻塞的,而且我无法使用此方法实现超时后的通知关闭。