using System; using System.Collections.Generic; using System.Threading; using UnityEngine; using Cysharp.Threading.Tasks; using Rokid.UXR; using Stary.Evo; namespace Main { public class CancellationTokenCore : MonoBehaviour { #region Instance private static CancellationTokenCore m_Instance; /// /// Singleton Object /// public static CancellationTokenCore Instance { get { if (m_Instance == null) { CancellationTokenCore[] ts = GameObject.FindObjectsOfType(); if (ts != null && ts.Length > 0) { if (ts.Length == 1) { m_Instance = ts[0]; } else { throw new Exception(string.Format( "## Uni Exception ## Cls:{0} Info:Singleton not allows more than one instance", typeof(CancellationTokenCore))); } } else { m_Instance = new GameObject(string.Format("{0}(Singleton)", typeof(CancellationTokenCore).ToString())) .AddComponent(); } } return m_Instance; } } #endregion // 存储 CancellationTokenSource 实例的字典 private readonly Dictionary _cancellationTokenSources = new Dictionary(); /// /// 获取一个 CancellationTokenSource 实例,如果不存在则创建一个 /// /// 用于标识 CancellationTokenSource 的键 /// CancellationTokenSource 实例 public CancellationToken CancellationTokenSource(string key) { if (_cancellationTokenSources.TryGetValue(key, out var cts)) { CancelCancellationTokenSource(key); } cts = new CancellationTokenSource(); _cancellationTokenSources[key] = cts; return cts.Token; } /// /// 取消指定键对应的 CancellationTokenSource 实例 /// /// 用于标识 CancellationTokenSource 的键 public void CancelCancellationTokenSource(string key) { if (_cancellationTokenSources.TryGetValue(key, out var cts)) { try { cts.Cancel(); cts.Dispose(); } catch (OperationCanceledException) { Debug.Log($"ComponentExtensions:【{key}】异步任务被取消"); } _cancellationTokenSources.Remove(key); } } /// /// 取消所有的 CancellationTokenSource 实例 /// public void CancelAllCancellationTokenSources() { foreach (var cts in _cancellationTokenSources.Values) { try { cts.Cancel(); cts.Dispose(); } catch (OperationCanceledException) { Debug.Log($"ComponentExtensions:全部异步任务被取消"); } } _cancellationTokenSources.Clear(); } private void OnDestroy() { // 在对象销毁时取消所有的 CancellationTokenSource 实例 CancelAllCancellationTokenSources(); } } public static class ComponentExtensions { /// /// 获取组件的CancellationTokenSource,当组件销毁时,会取消该CancellationTokenSource /// /// /// private static CancellationToken CancellationTokenOnDestroy(this GameObject component) { var cts = new CancellationTokenSource(); component.GetOrAddComponent() .OnDestroyEvent += () => { try { cts.Cancel(); cts.Dispose(); } catch (OperationCanceledException) { Debug.Log($"ComponentExtensions:【{component.name}】异步任务被取消"); } }; return cts.Token; } class DestroyNotifier : MonoBehaviour { public event System.Action OnDestroyEvent; private void OnDestroy() { OnDestroyEvent?.Invoke(); } } } }