diff --git a/Assets/YooAsset/Runtime/OperationSystem/AsyncOperationBase.cs b/Assets/YooAsset/Runtime/OperationSystem/AsyncOperationBase.cs index 3cef6e73..f48121df 100644 --- a/Assets/YooAsset/Runtime/OperationSystem/AsyncOperationBase.cs +++ b/Assets/YooAsset/Runtime/OperationSystem/AsyncOperationBase.cs @@ -244,12 +244,15 @@ namespace YooAsset Error = "user abort"; YooLogger.Warning($"Async operation {this.GetType().Name} has been aborted !"); } + + //注意:强制收尾,确保Task能完成 + FinishOperation(); } /// /// 强制结束异步任务 /// - internal void FinishOperation() + private void FinishOperation() { if (IsFinish == false) { @@ -307,12 +310,7 @@ namespace YooAsset // 当执行次数用完时 runCount--; if (runCount <= 0) - { - Status = EOperationStatus.Failed; - Error = $"Operation {this.GetType().Name} failed to wait for async complete !"; - YooLogger.Error(Error); break; - } } } @@ -341,9 +339,6 @@ namespace YooAsset /// public void WaitForAsyncComplete() { - if (IsDone) - return; - //TODO 防止异步操作被挂起陷入无限死循环! // 例如:文件解压任务或者文件导入任务! if (Status == EOperationStatus.None) @@ -354,7 +349,19 @@ namespace YooAsset if (IsWaitForAsyncComplete == false) { IsWaitForAsyncComplete = true; - InternalWaitForAsyncComplete(); + + if (IsDone == false) + InternalWaitForAsyncComplete(); + + if (IsDone == false) + { + Status = EOperationStatus.Failed; + Error = $"Operation {this.GetType().Name} failed to wait for async complete !"; + YooLogger.Error(Error); + } + + //注意:强制收尾,确保Task能完成 + FinishOperation(); } } diff --git a/Assets/YooAsset/Runtime/OperationSystem/OperationScheduler.cs b/Assets/YooAsset/Runtime/OperationSystem/OperationScheduler.cs index c12ac0de..cef60108 100644 --- a/Assets/YooAsset/Runtime/OperationSystem/OperationScheduler.cs +++ b/Assets/YooAsset/Runtime/OperationSystem/OperationScheduler.cs @@ -104,7 +104,6 @@ namespace YooAsset foreach (var operation in _newList) { operation.AbortOperation(); - operation.FinishOperation(); //注意:强制收尾,确保Task能完成 } _newList.Clear(); @@ -112,7 +111,6 @@ namespace YooAsset foreach (var operation in _operations) { operation.AbortOperation(); - operation.FinishOperation(); //注意:强制收尾,确保Task能完成 } _operations.Clear(); } diff --git a/Assets/YooAsset/Runtime/OperationSystem/README.md b/Assets/YooAsset/Runtime/OperationSystem/README.md index 14bffc49..128659b4 100644 --- a/Assets/YooAsset/Runtime/OperationSystem/README.md +++ b/Assets/YooAsset/Runtime/OperationSystem/README.md @@ -322,7 +322,8 @@ operation.Priority = 100; // 设置高优先级 **排序规则:** - 新操作添加时:若新增队列存在非零优先级,则触发排序 -- 运行时修改 `Priority`:会在下一次调度器更新时自动触发重排(即时生效,通常为下一帧) +- 运行中修改 `Priority`:调度器会在每帧 `Update()` 的排序阶段检测 `IsDirty` 并触发重排;若在某个操作的 `InternalUpdate()` 内修改(本帧排序已完成),则新的优先级会延后一帧生效(可能与预期不符) +- 若期望本帧生效:请尽量在任务入队前或本帧调度器 `Update()` 开始前设置 `Priority`,避免在 `InternalUpdate()` 内临时调整 - 排序使用 `List.Sort()` 进行原地排序;频繁修改优先级会带来额外排序开销,建议按需使用 ### 时间切片