Unity MyFramework 用法说明(十七):使用 WaitingManager 统一等待异步任务与业务条件

发布时间:2026/7/24 15:39:46

Unity MyFramework 用法说明(十七):使用 WaitingManager 统一等待异步任务与业务条件 上一篇介绍了AsyncTaskGroup它适合等待多个异步操作全部完成。实际业务中流程开始的条件不一定都是异步任务。例如进入战斗前除了等待地图加载还可能需要等待玩家创建完成、服务器场景数据到达。MyFramework 提供了WaitingManager用于把这些等待条件统一封装起来。项目地址https://github.com/ZHOURUIH/MyFramework一、WaitingManager 解决什么问题假设进入战斗需要满足三个条件地图资源加载完成 玩家角色创建完成 服务器场景数据接收完成直接写在update()中public override void update(float elapsedTime) { base.update(elapsedTime); if (!mMapLoaded || !mPlayerCreated || !mServerDataReady) { return; } enterBattle(); }还需要额外保证enterBattle()只执行一次并在流程退出后停止检查。使用WaitingManager后可以直接描述等待什么 ↓ 全部满足 ↓ 执行什么二、等待一个业务条件最简单的用法是等待一个BoolFunction返回trueusing static FrameBaseHotFix; protected bool mPlayerCreated; protected void waitPlayerCreated() { mWaitingManager.createWaiting( () mPlayerCreated, onPlayerCreated); } protected void onPlayerCreated() { log(玩家创建完成); }WaitingManager每帧检查条件。当条件第一次成立时会执行完成回调并自动销毁这个Waiting。不需要自己在update()中持续判断。三、同时等待多个条件通过createWaiting(Action)创建一个空的等待对象再逐项添加条件protected bool mPlayerCreated; protected bool mServerDataReady; protected bool mSceneInitialized; protected void waitEnterBattle() { Waiting waiting mWaitingManager.createWaiting(onEnterBattle); waiting.addCondition(() mPlayerCreated); waiting.addCondition(() mServerDataReady); waiting.addCondition(() mSceneInitialized); } protected void onEnterBattle() { log(所有条件完成进入战斗); }只有三个条件全部返回true才会调用onEnterBattle()。完成回调最多执行一次即使条件之后一直保持为true也不会重复触发。四、同时等待异步操作和业务条件Waiting不仅能添加条件也可以添加CustomAsyncOperationprotected bool mPlayerCreated; protected bool mServerDataReady; protected void prepareBattle() { CustomAsyncOperation mapOperation startLoadMap(); Waiting waiting mWaitingManager.createWaiting(onPrepareFinished); waiting.addAsyncOperation(mapOperation); waiting.addCondition(() mPlayerCreated); waiting.addCondition(() mServerDataReady); } protected void onPrepareFinished() { log(地图、玩家和服务器数据都已准备完成); } protected CustomAsyncOperation startLoadMap() { // 启动地图加载并返回对应的异步操作 return null; }判断规则是所有 CustomAsyncOperation 不再等待 并且 所有 BoolFunction 返回 true两部分同时满足后才会执行完成回调。传入的异步操作和条件不能为null否则检查时会出现空引用。五、快速等待一到三个异步操作WaitingManager还提供了常用重载mWaitingManager.createWaiting( operation, onFinished);等待两个异步操作mWaitingManager.createWaiting( mapOperation, playerOperation, onFinished);等待三个异步操作mWaitingManager.createWaiting( mapOperation, playerOperation, monsterOperation, onFinished);如果只有异步操作不需要额外业务条件直接使用这些重载更简洁。任务数量更多或者还要混合普通条件时再创建Waiting后逐项添加。六、获取简单进度Waiting可以计算当前进度float progress waiting.getProgress();它会把每一个异步操作和每一个业务条件都视为一项任务。例如共有四项其中两项完成进度 2 / 4 0.5可以用于显示简单的准备进度protected Waiting mWaiting; public float getPrepareProgress() { return mWaiting?.getProgress() ?? 1.0f; }需要注意它只是按照完成数量计算不会读取单个资源加载任务内部的真实百分比。未完成 计为 0 已完成 计为 1因此它适合显示整体步骤进度不适合代替精确的下载进度。七、等待过程中的取消条件当所属流程已经退出时原来的等待回调不应该继续执行。可以设置取消条件protected bool mCanceled; protected void beginWaiting() { mCanceled false; Waiting waiting mWaitingManager.createWaiting(onFinished); waiting.addCondition(() mPlayerCreated); waiting.addCondition(() mServerDataReady); waiting.setCancelCondition(() mCanceled); } protected void leaveCurrentFlow() { mCanceled true; }当取消条件返回true时不执行完成回调 自动销毁 Waiting默认创建的Waiting会自动销毁所以这里只需要修改取消条件。取消条件适合处理界面已经关闭 SceneProcedure 已经退出 玩家主动取消匹配 当前请求已经被新请求替代 对象准备销毁八、手动管理 Waiting 生命周期默认情况下等待完成或取消后会自动销毁Waiting waiting mWaitingManager.createWaiting(onFinished);等价于Waiting waiting mWaitingManager.createWaiting(onFinished, true);如果需要保存引用并由业务手动管理可以关闭自动销毁protected Waiting mWaiting; protected void beginWaiting() { mWaiting mWaitingManager.createWaiting( onFinished, false); mWaiting.addCondition(() mPlayerCreated); mWaiting.addCondition(() mServerDataReady); }完成后手动销毁protected void onFinished() { mWaitingManager.destroyWaiting(ref mWaiting); enterBattle(); }流程提前退出时取消protected void cancelWaiting() { mWaitingManager?.cancel(ref mWaiting); }cancel()会立即移除并回收等待对象同时将引用设置为null不会调用完成回调。关闭自动销毁后必须主动调用destroyWaiting(ref waiting);或者cancel(ref waiting);否则等待对象会一直保留在WaitingManager中。九、空 Waiting 的行为下面创建了一个没有任何条件的等待对象mWaitingManager.createWaiting(onFinished);没有条件时Waiting.isDone()会直接返回true。因此它会在WaitingManager下一次更新时执行回调而不是在createWaiting()中立即调用。这可以用来把一段逻辑延迟到下一次框架更新但最好只在确实需要这种行为时使用。十、和 AsyncTaskGroup 的区别两者都能等待多个任务但侧重点不同。AsyncTaskGroup主要等待多个异步操作资源A加载 资源B加载 资源C加载 ↓ 全部完成后回调适合资源预加载和批量异步初始化。WaitingManager可以混合等待异步操作 业务布尔条件 服务器数据状态 对象创建状态 ↓ 全部满足后回调选择方式可以概括为只组合多个异步任务 使用 AsyncTaskGroup 需要同时等待异步任务和业务状态 使用 WaitingManager十一、总结WaitingManager的基本用法是Waiting waiting mWaitingManager.createWaiting(onFinished); waiting.addAsyncOperation(operation); waiting.addCondition(() conditionA); waiting.addCondition(() conditionB);需要取消时waiting.setCancelCondition(() canceled);需要手动管理生命周期时mWaitingManager.cancel(ref waiting);它把原本散落在update()、异步回调和多个布尔字段中的判断集中成一个明确的等待对象添加异步操作 添加业务条件 设置取消条件 全部满足后统一回调这样进入场景、开始战斗、匹配完成和批量初始化等流程可以直接表达“需要等待什么”而不需要在各处重复维护完成判断。

相关新闻