03-05-架构篇-操作异步体系(OperationSystem)

通用异步体系(OperationSystem)

篇章 :03-架构篇 阅读时间 :约 35 分钟 前置知识:了解 Runtime 端系统架构


一、引言

本章将深入解析 YooAsset 的通用异步体系(OperationSystem)。OperationSystem 是 YooAsset 异步操作管理的核心,它通过统一的抽象和调度机制,实现了高效、灵活的异步操作管理。

YooAsset 的 OperationSystem 是一个独立的子系统,被广泛用于资源加载、下载、解密、缓存等场景。本章将详细解析 OperationSystem 的设计和实现。


二、OperationSystem 的概念

2.1 为什么需要 OperationSystem

在 Unity 中,异步操作是一个常见的需求。常见的异步操作包括:

  • 资源加载(LoadAssetAsync)
  • 场景加载(LoadSceneAsync)
  • 资源下载(DownloadAsync)
  • 文件读取(ReadFileAsync)

传统异步操作的挑战:

在传统的异步操作实现中,开发者需要处理以下问题:

  • 进度跟踪:如何跟踪异步操作的进度
  • 状态管理:如何管理异步操作的状态
  • 回调通知:如何在异步操作完成时通知调用者
  • 优先级管理:如何管理异步操作的优先级
  • 错误处理:如何处理异步操作中的错误

OperationSystem 的解决方案:

OperationSystem 通过统一的抽象和调度机制,提供了以下能力:

  • 统一的异步操作接口
  • 自动的进度跟踪
  • 自动的状态管理
  • 自动的回调通知
  • 灵活的优先级管理
  • 完善的错误处理

2.2 OperationSystem 的设计目标

OperationSystem 的设计目标如下:

统一性:

提供统一的异步操作接口,使所有异步操作都遵循相同的模式。

灵活性:

支持多种异步操作类型,可以灵活扩展新的异步操作。

可调度性:

支持异步操作的调度管理,可以控制异步操作的执行顺序和并发数。

可监控性:

支持异步操作的进度跟踪和状态查询。

2.3 OperationSystem 的组成

OperationSystem 由以下核心组件组成:

markdown 复制代码
OperationSystem 组成
├── Operation(异步操作)
│   ├── AsyncOperationBase(基类)
│   └── 具体操作实现
├── OperationSystem(调度器)
│   ├── 优先级队列
│   ├── 时间片管理
│   └── 操作执行
├── OperationUpdater(更新器)
│   └── 帧更新逻辑
└── OperationHandle(操作句柄)
    └── 对外接口

Operation 详解:

Operation 是异步操作的抽象,定义了异步操作的基本行为。具体的异步操作继承自 Operation,实现具体的逻辑。

OperationSystem 详解:

OperationSystem 是异步操作的调度器,负责管理所有异步操作的执行。

OperationUpdater 详解:

OperationUpdater 是异步操作的更新器,负责在每帧更新异步操作的状态。

OperationHandle 详解:

OperationHandle 是异步操作的句柄,对外暴露异步操作的接口。开发者通过 OperationHandle 与异步操作交互。


三、AsyncOperationBase 基类

3.1 AsyncOperationBase 的设计

AsyncOperationBase 是所有异步操作的基类,定义了异步操作的基本行为。

AsyncOperationBase 的属性:

csharp 复制代码
public abstract class AsyncOperationBase
{
    public EAsyncOperationStatus Status { get; protected set; }
    public float Progress { get; protected set; }
    public string Error { get; protected set; }
    public bool IsDone => Status != EAsyncOperationStatus.None;
    public event Action<AsyncOperationBase> OnCompleted;
    
    public abstract void Start();
    public abstract void Update();
    public abstract void Destroy();
}

Status 属性详解:

Status 表示异步操作的当前状态,包括 None、Running、Succeed、Failed 四个状态。

Progress 属性详解:

Progress 表示异步操作的进度,范围 0-1。

Error 属性详解:

Error 表示异步操作失败时的错误信息。

OnCompleted 事件详解:

OnCompleted 是异步操作完成时触发的事件,可以通过订阅该事件来获取完成通知。

3.2 异步操作的状态机

异步操作内部维护了一个状态机:

sql 复制代码
异步操作状态机
├── None:初始状态,操作尚未开始
├── Running:操作正在执行
├── Succeed:操作执行成功
└── Failed:操作执行失败

状态流转详解:

异步操作的状态流转如下:

  • None → Running:调用 Start 方法后
  • Running → Succeed:操作执行成功
  • Running → Failed:操作执行失败
  • Succeed/Failed → 销毁:调用 Destroy 方法

状态机的作用:

状态机确保异步操作在正确的状态下执行正确的操作,避免出现状态不一致的问题。

3.3 异步操作的生命周期

异步操作的生命周期如下:

  1. 创建:创建异步操作实例
  2. 启动:调用 Start 方法启动操作
  3. 更新:每帧调用 Update 方法更新操作状态
  4. 完成:操作完成后触发 OnCompleted 事件
  5. 销毁:调用 Destroy 方法销毁操作

创建详解:

创建异步操作实例时,会设置初始状态为 None,并初始化必要的字段。

启动详解:

调用 Start 方法启动异步操作。Start 方法会进行一些初始化工作(如加载资源、发送请求等),然后将状态设置为 Running。

更新详解:

每帧调用 Update 方法更新异步操作的状态。Update 方法会检查操作是否完成,并更新进度。

完成详解:

异步操作完成后,会将状态设置为 Succeed 或 Failed,并触发 OnCompleted 事件。

销毁详解:

调用 Destroy 方法销毁异步操作。Destroy 方法会清理异步操作占用的资源,如取消请求、释放内存等。


四、OperationSystem 调度器

4.1 OperationSystem 的工作原理

OperationSystem 是异步操作的调度器,负责管理所有异步操作的执行。

OperationSystem 的工作流程:

markdown 复制代码
OperationSystem 工作流程
1. 接收异步操作(通过 ProcessOperaiton 方法)
2. 将异步操作加入优先级队列
3. 每帧更新时:
   a. 按优先级处理队列中的操作
   b. 调用每个操作的 Update 方法
   c. 检查操作是否完成
   d. 完成的操作触发回调
4. 销毁完成的操作

4.2 优先级队列

OperationSystem 使用优先级队列管理异步操作:

优先级定义:

YooAsset 定义了多个优先级:

  • Low:低优先级
  • BelowNormal:低于正常
  • Normal:正常
  • AboveNormal:高于正常
  • High:高优先级
  • Ultra:超高优先级

优先级的作用:

优先级决定了异步操作的执行顺序。高优先级的操作会优先执行,适用于需要紧急处理的操作。

优先级的应用:

  • 资源加载:高优先级用于关键资源加载
  • 资源下载:低优先级用于后台资源下载
  • 缓存清理:低优先级用于后台缓存清理

4.3 时间片管理

OperationSystem 支持时间片管理,避免单帧执行过多异步操作:

时间片详解:

时间片是 OperationSystem 在单帧内可以执行异步操作的最大时间。超过时间片的操作会推迟到下一帧执行。

时间片的作用:

  • 避免阻塞主线程
  • 保证游戏帧率
  • 平滑处理大量异步操作

时间片配置:

csharp 复制代码
public class OperationSystem
{
    public float TimeSlice { get; set; } = 0.5f; // 默认 0.5 毫秒
}

4.4 OperationSystem 的实现

OperationSystem 的核心实现:

csharp 复制代码
public class OperationSystem
{
    private List<AsyncOperationBase> _operations;
    private List<AsyncOperationBase> _completeList;
    private List<AsyncOperationBase> _destroyList;
    
    public void ProcessOperaiton(AsyncOperationBase operation)
    {
        operation.Start();
        _operations.Add(operation);
    }
    
    public void Update()
    {
        // 更新所有操作
        float startTime = Time.realtimeSinceStartup;
        for (int i = 0; i < _operations.Count; i++)
        {
            _operations[i].Update();
            
            // 检查时间片
            if (Time.realtimeSinceStartup - startTime > TimeSlice)
                break;
        }
        
        // 处理完成的操作
        ProcessCompleted();
    }
}

五、OperationUpdater 更新器

5.1 OperationUpdater 的概念

OperationUpdater 是异步操作的更新器,负责在每帧更新异步操作的状态。

OperationUpdater 的设计:

OperationUpdater 是一个 MonoBehaviour,在 Unity 引擎的 Update 生命周期中调用 OperationSystem 的 Update 方法。

OperationUpdater 的实现:

csharp 复制代码
public class OperationUpdater : MonoBehaviour
{
    private void Update()
    {
        OperationSystem.Update();
    }
}

5.2 OperationUpdater 的初始化

OperationUpdater 在 YooAsset 初始化时创建:

csharp 复制代码
public class YooAssetsInitializer
{
    public static void Initialize()
    {
        // 创建 OperationUpdater GameObject
        GameObject updaterGo = new GameObject("OperationUpdater");
        GameObject.DontDestroyOnLoad(updaterGo);
        updaterGo.AddComponent<OperationUpdater>();
    }
}

5.3 OperationUpdater 的注意事项

DontDestroyOnLoad:

OperationUpdater 使用 DontDestroyOnLoad 确保在场景切换时不被销毁。

Update 顺序:

OperationUpdater 的 Update 在所有业务脚本的 Update 之后执行,确保业务脚本能获取到最新的异步操作状态。


六、OperationHandle 句柄

6.1 OperationHandle 的概念

OperationHandle 是异步操作的句柄,对外暴露异步操作的接口。

OperationHandle 的设计:

OperationHandle 是对 AsyncOperationBase 的包装,提供了更友好的 API。

OperationHandle 的实现:

csharp 复制代码
public class OperationHandle<T> where T : AsyncOperationBase
{
    private T _operation;
    
    public bool IsValid => _operation != null;
    public bool IsDone => _operation?.IsDone ?? false;
    public float Progress => _operation?.Progress ?? 0;
    public string Error => _operation?.Error;
    
    public T Operation => _operation;
    
    public event Action<OperationHandle<T>> OnCompleted;
    
    public void Release()
    {
        // 释放句柄
    }
}

6.2 OperationHandle 的使用

开发者使用 OperationHandle 与异步操作交互:

csharp 复制代码
// 发起异步操作
var handle = package.LoadAssetAsync<GameObject>("prefab_path");

// 注册完成回调
handle.OnCompleted += (op) => {
    if (op.Error == null)
    {
        GameObject prefab = op.Asset;
        // 使用资源
    }
};

// 等待完成
await handle.Task;

// 释放句柄
handle.Release();

6.3 OperationHandle 的引用计数

OperationHandle 使用引用计数管理生命周期:

引用计数的作用:

引用计数确保异步操作在所有引用都释放后才被销毁。

引用计数的方法:

  • AddRef():增加引用计数
  • Release():减少引用计数(引用计数为 0 时销毁)

七、异步操作类型

7.1 常见的异步操作类型

YooAsset 提供了多种异步操作类型:

资源加载操作:

csharp 复制代码
public class AssetProvider : ProviderOperation
{
    // 资源加载的具体实现
}

场景加载操作:

csharp 复制代码
public class SceneProvider : ProviderOperation
{
    // 场景加载的具体实现
}

下载操作:

csharp 复制代码
public class DownloadOperation : AsyncOperationBase
{
    // 资源下载的具体实现
}

解密操作:

csharp 复制代码
public class DecryptOperation : AsyncOperationBase
{
    // 资源解密的具体实现
}

Web 请求操作:

csharp 复制代码
public class WebRequestOperation : AsyncOperationBase
{
    // Web 请求的具体实现
}

7.2 自定义异步操作

开发者可以自定义异步操作,扩展 YooAsset 的功能:

自定义异步操作的步骤:

  1. 继承 AsyncOperationBase
  2. 实现 Start、Update、Destroy 方法
  3. 在合适的时机调用 Completed() 方法触发完成回调

自定义异步操作示例:

csharp 复制代码
public class CustomAsyncOperation : AsyncOperationBase
{
    public object Result { get; private set; }
    
    public override void Start()
    {
        Status = EAsyncOperationStatus.Running;
        // 启动自定义逻辑
    }
    
    public override void Update()
    {
        // 更新自定义逻辑
        if (/* 完成条件 */)
        {
            Result = /* 实际结果 */;
            Status = EAsyncOperationStatus.Succeed;
        }
    }
    
    public override void Destroy()
    {
        // 清理资源
    }
}

八、总结

本章深入解析了 YooAsset 通用异步体系(OperationSystem),包括:

  • OperationSystem 的概念:统一的异步操作管理
  • AsyncOperationBase 基类:异步操作的基础抽象
  • OperationSystem 调度器:异步操作的调度管理
  • OperationUpdater 更新器:异步操作的帧更新
  • OperationHandle 句柄:对外暴露的异步操作接口
  • 异步操作类型:常见和自定义的异步操作

OperationSystem 是 YooAsset 异步操作管理的核心,它通过统一的抽象和调度机制,为 YooAsset 的所有异步操作提供了高效、灵活、可靠的运行环境。


上一篇 :文件系统架构(IFileSystem) 下一篇 :资源下载器架构

相关推荐
SmalBox1 天前
03-04-架构篇-文件系统架构(IFileSystem)
unity3d·游戏开发
甲维斯9 天前
Opus5.5大考!做一个赛车游戏"秋名山车神"
人工智能·游戏开发
鑫鑫哥adam11 天前
一个 1x1 贴图,是怎么炸掉整个热更包的?
unity3d·游戏开发
Behavior12 天前
Unity 手游动态更换 App 图标 — Android 与 iOS 双端技术方案
c#·unity3d·游戏开发
SmalBox12 天前
03-03-架构篇-Runtime加载系统架构
unity3d·游戏开发
SmalBox12 天前
03-02-架构篇-Editor打包系统架构
unity3d·游戏开发
Yeah12712 天前
当 LLM 进入游戏玩法:从收权到放权
游戏开发
Behavior12 天前
Unity 手游 iOS Deep Link 唤醒全流程:从 URL Scheme / Universal Links 到 C# 层参数投递
c#·unity3d·游戏开发
SmalBox12 天前
03-01-架构篇-整体架构总览
unity3d·游戏开发