GFramework/docs/zh-CN/core/async-initialization.md
GeWuYou 93b25a19f7 docs(core): 更新命令系统文档并移除控制器独立文档
- 移除 controller.md 文件,将控制器相关内容整合到其他文档中
- 重构 command.md 文档,更新命令基类的类型参数设计
- 添加新的命令基类 AbstractCommand<TInput> 和 AbstractCommand<TInput, TResult>
- 更新命令使用示例,采用输入参数对象替代构造函数参数
- 优化事件注册相关代码示例,移除 Godot 特定的生命周期方法
- 更新依赖注入容器文档,明确 Register 方法的泛型特性
- 添加模型异步初始化功能说明和相关接口介绍
- 重构查询系统文档,统一采用输入参数对象的设计模式
- 更新架构生命周期枚举值,使用更准确的阶段名称
- 添加 GitHub Actions 工作流配置,集成 LLM 准备的文档索引功能
2026-02-12 13:13:07 +08:00

10 KiB
Raw Permalink Blame History

异步初始化指南

概述

异步初始化是 GFramework 中的一个重要特性,允许 Architecture、Model、System 等组件在初始化时执行异步操作。这对于需要加载大量资源、进行网络请求或其他耗时操作的场景特别有用。

核心接口

IAsyncInitializable

异步初始化接口,定义了异步初始化的契约。

核心方法:

Task InitializeAsync();  // 异步初始化方法

实现者:

  • Architecture - 架构支持异步初始化
  • AbstractModel - Model 可以实现异步初始化
  • AbstractSystem - System 可以实现异步初始化
  • AbstractUtility - Utility 可以实现异步初始化

异步 Architecture

基本使用

public class GameArchitecture : Architecture
{
    protected override void Init()
    {
        // 同步初始化逻辑
        RegisterModel(new PlayerModel());
        RegisterSystem(new CombatSystem());
    }
}

// 异步初始化架构
var architecture = new GameArchitecture();
await architecture.InitializeAsync();

// 等待架构就绪
await architecture.WaitUntilReadyAsync();

初始化流程

异步初始化遵循以下流程:

  1. 创建架构实例
  2. 调用 InitializeAsync() 方法
  3. 执行同步初始化(Init() 方法)
  4. 按顺序异步初始化各个阶段:
    • 工具异步初始化BeforeUtilityInit → AfterUtilityInit
    • 模型异步初始化BeforeModelInit → AfterModelInit
    • 系统异步初始化BeforeSystemInit → AfterSystemInit
  5. 进入 Ready 阶段
  6. 返回 Task 完成

定义异步 Model

public class ConfigModel : AbstractModel, IAsyncInitializable
{
    public BindableProperty<GameConfig> Config { get; } = new(null);

    protected override void OnInit()
    {
        // 同步初始化逻辑
        Console.WriteLine("ConfigModel sync init");
    }

    public async Task InitializeAsync()
    {
        // 异步加载配置
        var storage = this.GetUtility<IStorageUtility>();
        var config = await storage.LoadConfigAsync();
        Config.Value = config;

        Console.WriteLine("ConfigModel async init completed");
        this.SendEvent(new ConfigLoadedEvent { Config = config });
    }
}

public class PlayerDataModel : AbstractModel, IAsyncInitializable
{
    public BindableProperty<PlayerData> PlayerData { get; } = new(null);

    protected override void OnInit()
    {
        // 同步初始化逻辑
    }

    public async Task InitializeAsync()
    {
        // 异步加载玩家数据
        var storage = this.GetUtility<IStorageUtility>();
        var playerId = this.GetContext().Environment.Get<string>("PlayerId");
        var playerData = await storage.LoadPlayerDataAsync(playerId);
        PlayerData.Value = playerData;
    }
}

在架构中使用异步 Model

public class GameArchitecture : Architecture
{
    protected override void Init()
    {
        // 注册异步 Model
        RegisterModel(new ConfigModel());
        RegisterModel(new PlayerDataModel());
        RegisterModel(new PlayerModel());

        // 注册 System
        RegisterSystem(new CombatSystem());
    }
}

// 使用
var architecture = new GameArchitecture();
await architecture.InitializeAsync();

异步 System

定义异步 System

public class DataLoadSystem : AbstractSystem, IAsyncInitializable
{
    private GameData _gameData;

    protected override void OnInit()
    {
        // 同步初始化逻辑
        this.RegisterEvent<GameStartedEvent>(OnGameStarted);
    }

    public async Task InitializeAsync()
    {
        // 异步加载游戏数据
        var storage = this.GetUtility<IStorageUtility>();
        _gameData = await storage.LoadGameDataAsync();

        Console.WriteLine("Game data loaded");
        this.SendEvent(new GameDataLoadedEvent { Data = _gameData });
    }

    private void OnGameStarted(GameStartedEvent e)
    {
        Console.WriteLine($"Game started with data version: {_gameData.Version}");
    }
}

public class ResourceLoadSystem : AbstractSystem, IAsyncInitializable
{
    private Dictionary<string, Resource> _resources = new();

    protected override void OnInit()
    {
        // 同步初始化逻辑
    }

    public async Task InitializeAsync()
    {
        // 异步加载资源
        var resourceManager = this.GetUtility<IResourceManager>();
        _resources = await resourceManager.LoadAllResourcesAsync();

        Console.WriteLine($"Loaded {_resources.Count} resources");
    }
}

异步 Utility

定义异步 Utility

public class DatabaseUtility : IUtility, IAsyncInitializable
{
    private Database _database;

    public void Init()
    {
        // 同步初始化逻辑
    }

    public async Task InitializeAsync()
    {
        // 异步连接数据库
        _database = new Database();
        await _database.ConnectAsync("connection_string");

        Console.WriteLine("Database connected");
    }

    public async Task<T> QueryAsync<T>(string sql)
    {
        return await _database.QueryAsync<T>(sql);
    }
}

完整示例

场景:游戏启动流程

// 1. 定义各个异步组件
public class ConfigModel : AbstractModel, IAsyncInitializable
{
    public BindableProperty<GameConfig> Config { get; } = new(null);

    protected override void OnInit() { }

    public async Task InitializeAsync()
    {
        var storage = this.GetUtility<IStorageUtility>();
        Config.Value = await storage.LoadConfigAsync();
    }
}

public class PlayerModel : AbstractModel, IAsyncInitializable
{
    public BindableProperty<PlayerData> PlayerData { get; } = new(null);

    protected override void OnInit() { }

    public async Task InitializeAsync()
    {
        var storage = this.GetUtility<IStorageUtility>();
        var playerId = this.GetContext().Environment.Get<string>("PlayerId");
        PlayerData.Value = await storage.LoadPlayerDataAsync(playerId);
    }
}

public class ResourceLoadSystem : AbstractSystem, IAsyncInitializable
{
    private Dictionary<string, Resource> _resources = new();

    protected override void OnInit()
    {
        this.RegisterEvent<GameStartedEvent>(OnGameStarted);
    }

    public async Task InitializeAsync()
    {
        var resourceManager = this.GetUtility<IResourceManager>();
        _resources = await resourceManager.LoadAllResourcesAsync();
    }

    private void OnGameStarted(GameStartedEvent e)
    {
        Console.WriteLine("Game started with all resources loaded");
    }
}

// 2. 定义架构
public class GameArchitecture : Architecture
{
    protected override void Init()
    {
        RegisterModel(new ConfigModel());
        RegisterModel(new PlayerModel());
        RegisterSystem(new ResourceLoadSystem());
        RegisterSystem(new CombatSystem());
    }
}

// 3. 使用架构
public class GameBootstrapper
{
    public async Task StartGameAsync()
    {
        var architecture = new GameArchitecture();

        // 异步初始化架构
        await architecture.InitializeAsync();

        // 等待架构就绪
        await architecture.WaitUntilReadyAsync();

        Console.WriteLine("Game is ready!");

        // 发送游戏启动事件
        architecture.SendEvent(new GameStartedEvent());
    }
}

同步 vs 异步初始化

同步初始化

var architecture = new GameArchitecture();
architecture.Initialize();  // 阻塞等待初始化完成

// 立即可以使用架构
var playerModel = architecture.GetModel<PlayerModel>();

特点:

  • 阻塞式,等待初始化完成
  • 适用于简单场景或控制台应用
  • 初始化失败时抛出异常

异步初始化

var architecture = new GameArchitecture();
await architecture.InitializeAsync();  // 非阻塞等待

// 初始化完成后可以使用架构
var playerModel = architecture.GetModel<PlayerModel>();

特点:

  • 非阻塞式,不会阻塞主线程
  • 支持异步组件初始化
  • 适用于需要加载大量资源的场景
  • 初始化失败时抛出异常

最佳实践

1. 合理划分同步和异步初始化

public class MyModel : AbstractModel, IAsyncInitializable
{
    protected override void OnInit()
    {
        // 同步初始化:快速的初始化逻辑
        // - 注册事件监听
        // - 初始化本地数据结构
        // - 设置默认值
    }

    public async Task InitializeAsync()
    {
        // 异步初始化:耗时的初始化逻辑
        // - 加载文件
        // - 网络请求
        // - 数据库查询
    }
}

2. 处理异步初始化异常

public async Task StartGameAsync()
{
    var architecture = new GameArchitecture();

    try
    {
        await architecture.InitializeAsync();
    }
    catch (Exception ex)
    {
        Console.WriteLine($"Initialization failed: {ex.Message}");
        // 处理初始化失败
    }
}

3. 显示加载进度

public class ProgressTrackingArchitecture : Architecture
{
    public event Action<float> OnProgressChanged;

    protected override void Init()
    {
        RegisterModel(new ConfigModel());
        RegisterModel(new PlayerModel());
        RegisterSystem(new ResourceLoadSystem());
    }

    public async Task InitializeAsyncWithProgress()
    {
        OnProgressChanged?.Invoke(0.0f);

        // 初始化各个阶段
        await InitializeAsync();

        OnProgressChanged?.Invoke(1.0f);
    }
}

// 使用
var architecture = new ProgressTrackingArchitecture();
architecture.OnProgressChanged += progress =>
{
    Console.WriteLine($"Loading: {progress * 100}%");
};

await architecture.InitializeAsyncWithProgress();

4. 超时控制

public async Task StartGameWithTimeoutAsync()
{
    var architecture = new GameArchitecture();
    var cts = new CancellationTokenSource(TimeSpan.FromSeconds(30));

    try
    {
        var initTask = architecture.InitializeAsync();
        await initTask.ConfigureAwait(false);
    }
    catch (OperationCanceledException)
    {
        Console.WriteLine("Initialization timeout");
    }
}

相关包

  • architecture - 架构核心,支持异步初始化
  • model - Model 可以实现异步初始化
  • system - System 可以实现异步初始化
  • utility - Utility 可以实现异步初始化

许可证Apache 2.0