gpui-async
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseOverview
概述
GPUI provides integrated async runtime for foreground UI updates and background computation.
Key Concepts:
- Foreground tasks: UI thread, can update entities ()
cx.spawn - Background tasks: Worker threads, CPU-intensive work ()
cx.background_spawn - All entity updates happen on foreground thread
GPUI 为前台UI更新和后台计算提供了集成的异步运行时。
核心概念:
- 前台任务:运行在UI线程,可更新实体()
cx.spawn - 后台任务:运行在工作线程,适用于CPU密集型工作()
cx.background_spawn - 所有实体更新均在前台线程执行
Quick Start
快速开始
Foreground Tasks (UI Updates)
前台任务(UI更新)
rust
impl MyComponent {
fn fetch_data(&mut self, cx: &mut Context<Self>) {
let entity = cx.entity().downgrade();
cx.spawn(async move |cx| {
// Runs on UI thread, can await and update entities
let data = fetch_from_api().await;
entity.update(cx, |state, cx| {
state.data = Some(data);
cx.notify();
}).ok();
}).detach();
}
}rust
impl MyComponent {
fn fetch_data(&mut self, cx: &mut Context<Self>) {
let entity = cx.entity().downgrade();
cx.spawn(async move |cx| {
// 运行在UI线程,可等待并更新实体
let data = fetch_from_api().await;
entity.update(cx, |state, cx| {
state.data = Some(data);
cx.notify();
}).ok();
}).detach();
}
}Background Tasks (Heavy Work)
后台任务(繁重工作)
rust
impl MyComponent {
fn process_file(&mut self, cx: &mut Context<Self>) {
let entity = cx.entity().downgrade();
cx.background_spawn(async move {
// Runs on background thread, CPU-intensive
let result = heavy_computation().await;
result
})
.then(cx.spawn(move |result, cx| {
// Back to foreground to update UI
entity.update(cx, |state, cx| {
state.result = result;
cx.notify();
}).ok();
}))
.detach();
}
}rust
impl MyComponent {
fn process_file(&mut self, cx: &mut Context<Self>) {
let entity = cx.entity().downgrade();
cx.background_spawn(async move {
// 运行在后台线程,处理CPU密集型工作
let result = heavy_computation().await;
result
})
.then(cx.spawn(move |result, cx| {
// 返回前台更新UI
entity.update(cx, |state, cx| {
state.result = result;
cx.notify();
}).ok();
}))
.detach();
}
}Task Management
任务管理
rust
struct MyView {
_task: Task<()>, // Prefix with _ if stored but not accessed
}
impl MyView {
fn new(cx: &mut Context<Self>) -> Self {
let entity = cx.entity().downgrade();
let _task = cx.spawn(async move |cx| {
// Task automatically cancelled when dropped
loop {
tokio::time::sleep(Duration::from_secs(1)).await;
entity.update(cx, |state, cx| {
state.tick();
cx.notify();
}).ok();
}
});
Self { _task }
}
}rust
struct MyView {
_task: Task<()>, // 若仅存储不访问则添加前缀_
}
impl MyView {
fn new(cx: &mut Context<Self>) -> Self {
let entity = cx.entity().downgrade();
let _task = cx.spawn(async move |cx| {
// 任务在被丢弃时自动取消
loop {
tokio::time::sleep(Duration::from_secs(1)).await;
entity.update(cx, |state, cx| {
state.tick();
cx.notify();
}).ok();
}
});
Self { _task }
}
}Core Patterns
核心模式
1. Async Data Fetching
1. 异步数据获取
rust
cx.spawn(async move |cx| {
let data = fetch_data().await?;
entity.update(cx, |state, cx| {
state.data = Some(data);
cx.notify();
})?;
Ok::<_, anyhow::Error>(())
}).detach();rust
cx.spawn(async move |cx| {
let data = fetch_data().await?;
entity.update(cx, |state, cx| {
state.data = Some(data);
cx.notify();
})?;
Ok::<_, anyhow::Error>(())
}).detach();2. Background Computation + UI Update
2. 后台计算 + UI更新
rust
cx.background_spawn(async move {
heavy_work()
})
.then(cx.spawn(move |result, cx| {
entity.update(cx, |state, cx| {
state.result = result;
cx.notify();
}).ok();
}))
.detach();rust
cx.background_spawn(async move {
heavy_work()
})
.then(cx.spawn(move |result, cx| {
entity.update(cx, |state, cx| {
state.result = result;
cx.notify();
}).ok();
}))
.detach();3. Periodic Tasks
3. 周期性任务
rust
cx.spawn(async move |cx| {
loop {
tokio::time::sleep(Duration::from_secs(5)).await;
// Update every 5 seconds
}
}).detach();rust
cx.spawn(async move |cx| {
loop {
tokio::time::sleep(Duration::from_secs(5)).await;
// 每5秒更新一次
}
}).detach();4. Task Cancellation
4. 任务取消
Tasks are automatically cancelled when dropped. Store in struct to keep alive.
任务在被丢弃时会自动取消。若要保持任务存活,需将其存储在结构体中。
Common Pitfalls
常见陷阱
❌ Don't: Update entities from background tasks
❌ 错误做法:从后台任务更新实体
rust
// ❌ Wrong: Can't update entities from background thread
cx.background_spawn(async move {
entity.update(cx, |state, cx| { // Compile error!
state.data = data;
});
});rust
// ❌ 错误:无法从后台线程更新实体
cx.background_spawn(async move {
entity.update(cx, |state, cx| { // 编译错误!
state.data = data;
});
});✅ Do: Use foreground task or chain
✅ 正确做法:使用前台任务或链式调用
rust
// ✅ Correct: Chain with foreground task
cx.background_spawn(async move { data })
.then(cx.spawn(move |data, cx| {
entity.update(cx, |state, cx| {
state.data = data;
cx.notify();
}).ok();
}))
.detach();rust
// ✅ 正确:与前台任务链式调用
cx.background_spawn(async move { data })
.then(cx.spawn(move |data, cx| {
entity.update(cx, |state, cx| {
state.data = data;
cx.notify();
}).ok();
}))
.detach();Reference Documentation
参考文档
Complete Guides
完整指南
-
API Reference: See api-reference.md
- Task types, spawning methods, contexts
- Executors, cancellation, error handling
-
Patterns: See patterns.md
- Data fetching, background processing
- Polling, debouncing, parallel tasks
- Pattern selection guide
-
Best Practices: See best-practices.md
- Error handling, cancellation
- Performance optimization, testing
- Common pitfalls and solutions
-
API参考:查看 api-reference.md
- 任务类型、生成方法、上下文
- 执行器、取消机制、错误处理
-
模式指南:查看 patterns.md
- 数据获取、后台处理
- 轮询、防抖、并行任务
- 模式选择指南
-
最佳实践:查看 best-practices.md
- 错误处理、任务取消
- 性能优化、测试
- 常见陷阱与解决方案