diff --git a/Assets/YooAsset/Runtime/ResourceManager/Operation/UnloadAllAssetsOperation.cs b/Assets/YooAsset/Runtime/ResourceManager/Operation/UnloadAllAssetsOperation.cs index a8b58e23..250f4ebe 100644 --- a/Assets/YooAsset/Runtime/ResourceManager/Operation/UnloadAllAssetsOperation.cs +++ b/Assets/YooAsset/Runtime/ResourceManager/Operation/UnloadAllAssetsOperation.cs @@ -25,6 +25,7 @@ namespace YooAsset CheckOptions, ReleaseAll, TryAbortLoader, + RequestForceDestroy, CheckLoading, DestroyAll, Done, @@ -93,6 +94,17 @@ namespace YooAsset { loader.TryAbortLoader(); } + _steps = ESteps.RequestForceDestroy; + } + + if (_steps == ESteps.RequestForceDestroy) + { + // 向所有资源提供者下发强制销毁请求 + // 注意:防止零引用且尚未进入加载阶段的任务被无限挂起,从而导致 CheckLoading 死锁。 + foreach (var provider in _resManager.ProviderDic.Values) + { + provider.RequestForceDestroy(); + } _steps = ESteps.CheckLoading; } diff --git a/Assets/YooAsset/Runtime/ResourceManager/Provider/ProviderOperation.cs b/Assets/YooAsset/Runtime/ResourceManager/Provider/ProviderOperation.cs index 462eaeff..58d00093 100644 --- a/Assets/YooAsset/Runtime/ResourceManager/Provider/ProviderOperation.cs +++ b/Assets/YooAsset/Runtime/ResourceManager/Provider/ProviderOperation.cs @@ -67,6 +67,11 @@ namespace YooAsset /// public bool IsDestroyed { private set; get; } = false; + /// + /// 是否已收到强制销毁请求 + /// + public bool ForceDestroyRequested { private set; get; } = false; + /// /// 加载任务是否进行中 /// @@ -119,6 +124,18 @@ namespace YooAsset if (_steps == ESteps.None || _steps == ESteps.Done) return; + // 注意:收到强制销毁请求时,未在加载中的任务立即结束,防止零引用任务被无限挂起导致卸载流程死锁! + if (ForceDestroyRequested) + { + if (IsLoading == false) + { + InvokeCompletion("Provider force destroyed during unload all assets !", EOperationStatus.Failed); + return; + } + + // 注意:已进入加载阶段则继续等待自然完成 + } + // 注意:未在加载中的任务可以挂起! if (IsLoading == false) { @@ -199,11 +216,24 @@ namespace YooAsset } protected abstract void ProcessBundleResult(); + /// + /// 请求强制销毁 + /// 注意:用于卸载流程,标记后未在加载中的任务会在下一次更新时立即结束。 + /// + public void RequestForceDestroy() + { + ForceDestroyRequested = true; + } + /// /// 销毁资源提供者 + /// 注意:该方法是幂等的,重复调用不会重复释放资源。 /// public void DestroyProvider() { + if (IsDestroyed) + return; + IsDestroyed = true; // 检测是否为正常销毁