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;
// 检测是否为正常销毁