gpui-async

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Overview

概述

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
    • 错误处理、任务取消
    • 性能优化、测试
    • 常见陷阱与解决方案