From b1ea1249a98c46cabd3b67d29427ffeacceb50ae Mon Sep 17 00:00:00 2001 From: xiaji Date: Fri, 17 Apr 2026 07:43:20 +0800 Subject: [PATCH] Fix hang by using request_repaint in async thread --- src/gui.rs | 41 +++++++++++++++++++++++++++++++---------- 1 file changed, 31 insertions(+), 10 deletions(-) diff --git a/src/gui.rs b/src/gui.rs index 4f2545f..0f7a7d3 100644 --- a/src/gui.rs +++ b/src/gui.rs @@ -335,18 +335,24 @@ impl eframe::App for App { let node = node_ref.clone(); let vm_id = *id; let state_clone = state.clone(); + let ctx_clone = ctx.clone(); if ui.button("▶").clicked() { state_clone.write().unwrap().add_log(&format!("启动 VM {}...", vm_id)); - ctx.request_repaint(); thread::spawn(move || { let rt = tokio::runtime::Runtime::new().unwrap(); rt.block_on(async { let client = client.lock().unwrap(); if let Some(c) = client.as_ref() { match c.start_vm(&node, vm_id).await { - Ok(_) => state_clone.write().unwrap().add_log("✓ 启动成功"), - Err(e) => state_clone.write().unwrap().add_log(&format!("✗ {}", e)), + Ok(_) => { + state_clone.write().unwrap().add_log("✓ 启动成功"); + ctx_clone.request_repaint(); + } + Err(e) => { + state_clone.write().unwrap().add_log(&format!("✗ {}", e)); + ctx_clone.request_repaint(); + } } } }); @@ -357,17 +363,23 @@ impl eframe::App for App { let node2 = node_ref.clone(); let vm_id2 = *id; let state2 = state.clone(); + let ctx2 = ctx.clone(); if ui.button("■").clicked() { state2.write().unwrap().add_log(&format!("停止 VM {}...", vm_id2)); - ctx.request_repaint(); thread::spawn(move || { let rt = tokio::runtime::Runtime::new().unwrap(); rt.block_on(async { let client = client2.lock().unwrap(); if let Some(c) = client.as_ref() { match c.stop_vm(&node2, vm_id2).await { - Ok(_) => state2.write().unwrap().add_log("✓ 停止成功"), - Err(e) => state2.write().unwrap().add_log(&format!("✗ {}", e)), + Ok(_) => { + state2.write().unwrap().add_log("✓ 停止成功"); + ctx2.request_repaint(); + } + Err(e) => { + state2.write().unwrap().add_log(&format!("✗ {}", e)); + ctx2.request_repaint(); + } } } }); @@ -378,9 +390,9 @@ impl eframe::App for App { let node3 = node_ref.clone(); let vm_id3 = *id; let state3 = state.clone(); + let ctx3 = ctx.clone(); if ui.button("↻").clicked() { state3.write().unwrap().add_log(&format!("重启 VM {}...", vm_id3)); - ctx.request_repaint(); thread::spawn(move || { let rt = tokio::runtime::Runtime::new().unwrap(); rt.block_on(async { @@ -390,11 +402,20 @@ impl eframe::App for App { Ok(_) => { tokio::time::sleep(tokio::time::Duration::from_secs(3)).await; match c.start_vm(&node3, vm_id3).await { - Ok(_) => state3.write().unwrap().add_log("✓ 重启成功"), - Err(e) => state3.write().unwrap().add_log(&format!("✗ {}", e)), + Ok(_) => { + state3.write().unwrap().add_log("✓ 重启成功"); + ctx3.request_repaint(); + } + Err(e) => { + state3.write().unwrap().add_log(&format!("✗ {}", e)); + ctx3.request_repaint(); + } } } - Err(e) => state3.write().unwrap().add_log(&format!("✗ {}", e)), + Err(e) => { + state3.write().unwrap().add_log(&format!("✗ {}", e)); + ctx3.request_repaint(); + } } } });