-
I'm using Commands that execute However, I noticed that while having 4 threads sleeping at the same time, my subscription stops working and I cannot react to keys being pressed. The UI thread works though, because UI elements do respond. I attach an example App which shows the same notification both for keys being pressed and a button being clicked. You'll notice that by using the button you can get as many simultaneous notifications as you want, but with the keyboard you'll get stuck at 4 (or possibly another number if your CPU has a different number of cores) notifications. Is this a bug or am I doing something wrong? Also, any better ideas on how to have UI elements disappearing after x seconds without firing a separate thread for each one? src/main.rs: use iced::Application;
#[derive(Debug, Clone)]
pub enum Message {
KeyPressed,
ClearNotification,
}
pub struct LockTest {
notifications: std::collections::LinkedList<String>,
button_state: iced::button::State,
}
pub async fn clear_notification() {
std::thread::sleep(std::time::Duration::from_secs(3));
}
impl iced::Application for LockTest {
type Message = Message;
type Executor = iced::executor::Default;
type Flags = ();
fn new(_flags: ()) -> (Self, iced::Command<Message>) {
return (
LockTest {
notifications: std::collections::LinkedList::new(),
button_state: iced::button::State::new(),
},
iced::Command::none(),
);
}
fn title(&self) -> String {
return String::from("LockTest");
}
fn subscription(&self) -> iced::Subscription<Message> {
return iced_native::subscription::events_with(|event, _status| {
return match event {
iced_native::Event::Keyboard(iced::keyboard::Event::KeyPressed {
modifiers: _,
key_code: _,
}) => Some(Message::KeyPressed),
_ => None,
};
});
}
fn update(&mut self, message: Message) -> iced::Command<Message> {
let mut command = iced::Command::none();
match message {
Message::KeyPressed => {
self.notifications.push_front(String::from("key pressed!"));
command = iced::Command::perform(
clear_notification(),
|_| Message::ClearNotification,
);
}
Message::ClearNotification => {
self.notifications.pop_back();
}
}
return command;
}
fn view(&mut self) -> iced::Element<Message> {
let mut column = iced::Column::new();
let mut row = iced::Row::new();
for notification in &mut self.notifications.iter().rev() {
column = column.push(iced::Text::new(&*notification));
}
row = row.push(column);
row = row.push(
iced::Button::new(
&mut self.button_state,
iced::Text::new("Click me or press a key")
).on_press(Message::KeyPressed)
);
return iced::Container::new(row)
.width(iced::Length::Fill)
.height(iced::Length::Fill)
.into();
}
}
pub fn main() -> iced::Result {
let settings = iced::Settings::default();
return LockTest::run(settings);
} Cargo.toml: [package]
name = "lock-test"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
iced = { version="0.4", features=[] }
iced_native = "0.5" |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 1 reply
-
Blocking in an async thread breaks the The thread pool used by the executor has a limited number of worker threads. Futures work by polling work. If you block in an async context, you can block all of the worker threads. You should use pub async fn clear_notification() {
tokio::time::sleep(std::time::Duration::from_secs(3)).await;
} |
Beta Was this translation helpful? Give feedback.
Blocking in an async thread breaks the
Future
contract!The thread pool used by the executor has a limited number of worker threads. Futures work by polling work. If you block in an async context, you can block all of the worker threads.
You should use
tokio::time::sleep
and enable thetokio
feature: