赞
踩
今天儿童节,犬子已经9个多月了,今天是他的第一个儿童节。中年得子,其乐无穷(音:ku bu kan yan)…回头是岸啊
一连创建5个异步任务[id 从0~4],先停止其中的第id == 4的任务,再停止所有的任务
在Unity中,CancellationTokenSource用于创建和控制CancellationToken实例,以便在需要时请求取消异步操作。CancellationToken实例是一种轻量级的结构,用于在异步操作执行期间检查是否已请求取消。
首先,您需要创建一个CancellationTokenSource实例,用于创建和控制CancellationToken实例。然后,将CancellationToken实例传递给您要执行的异步任务,以便在需要时请求取消操作。最后,您可以调用CancellationTokenSource实例的Cancel()方法来请求取消所有使用该CancellationToken的异步操作。
public async UniTask FlowAsync(CancellationToken ctk)
{
foreach (var script in scripts)
{
Debug.Log($"执行步骤:{script.name}");
await (script as IFlowAsync).FlowAsync(ctk);
}
}
#if UNITY_EDITOR
[ContextMenu("测试步骤")]
#endif
void testAsync()
{
var ctsInfo = TaskSingol.CreatCts(); //生成一个 cts 实例,TaskSingol的定义见下文《用多个CancellationTokenSource实例来管理多个异步任务管理》
FlowAsync(ctsInfo.cts.Token); //传入token
}
using System.Collections.Generic; using UnityEngine; using System.Threading; using System; using System.Linq; /// <summary> /// 任务信号 /// </summary> public static class TaskSingol { /// <summary> /// 任务信息 /// </summary> [Serializable] public class CtsInfo { /// <summary> /// 任务id /// </summary> [SerializeField] public int id; /// <summary> /// cst实例 /// </summary> [SerializeField] public CancellationTokenSource cts; } /// <summary> /// 任务池子 /// </summary> public static List<CtsInfo> ctsInfos = new List<CtsInfo>(); /// <summary> /// 任务编号【自增】 /// </summary> private static int id = 0; /// <summary> /// 创建一个任务 /// </summary> /// <returns></returns> public static CtsInfo CreatCts() { var cts = new CancellationTokenSource(); var ci = new CtsInfo{cts = cts,id = id}; id++; ctsInfos.Add(ci); return ci; } /// <summary> /// 取消所有的任务 /// </summary> public static void CancelAllTask() { ctsInfos.ForEach(ci=>ci.cts.Cancel()); } /// <summary> /// 取消指定的任务 /// </summary> public static void CancelTask(int id) { ctsInfos.Where(ci=>ci.id == id).ToList().ForEach(ci => ci.cts.Cancel()); } }
using System.Collections;
using System.Collections.Generic;
using System.Threading;
using UnityEngine;
using Cysharp.Threading.Tasks;
public class FlowA : MonoBehaviour, IFlowAsync
{
public async UniTask FlowAsync(CancellationToken ctk)
{
Debug.Log($"我是monobehaviourA {Time.realtimeSinceStartup}");
await UniTask.Delay(2000,cancellationToken:ctk);
Debug.Log($"UniTask.Delay(2000) {Time.realtimeSinceStartup}");
}
}
using System.Collections; using System.Collections.Generic; using System.Threading; using UnityEngine; using Cysharp.Threading.Tasks; public class FlowB : MonoBehaviour, IFlowAsync { public async UniTask FlowAsync(CancellationToken ctk) { Debug.Log($"我是monobehaviourB {Time.realtimeSinceStartup}"); await UniTask.Delay(2000,cancellationToken:ctk); Debug.Log($"UniTask.Delay(2000) {Time.realtimeSinceStartup}"); } }
测试内容:
启动一个任务
停止所有任务
停止指定任务【4】
using System; using System.Collections; using System.Collections.Generic; using System.Threading; using UnityEngine; using System.Threading.Tasks; using Cysharp.Threading.Tasks; public class TestTask : MonoBehaviour { private int idx; #if UNITY_EDITOR [ContextMenu("启动一个任务")] #endif void test() { var ctsInfo = TaskSingol.CreatCts(); RunTask(ctsInfo.id, ctsInfo.cts.Token); } #if UNITY_EDITOR [ContextMenu("停止所有任务")] #endif void test2() { TaskSingol.CancelAllTask(); Debug.Log("停止所有的任务"); } #if UNITY_EDITOR [ContextMenu("停止所有任务【4】")] #endif void test3() { TaskSingol.CancelTask(4); Debug.Log("停止任务4"); } public async UniTask RunTask(int taskIndex,CancellationToken ctk) { Debug.Log($"{taskIndex}:任务运行中,1/4等待五秒"); await UniTask.Delay(TimeSpan.FromSeconds(5),cancellationToken:ctk); Debug.Log($"{taskIndex}:任务运行中,2/4等待五秒"); await UniTask.Delay(TimeSpan.FromSeconds(5), cancellationToken: ctk); Debug.Log($"{taskIndex}:任务运行中,3/4等待五秒结束,再等5秒"); await UniTask.Delay(TimeSpan.FromSeconds(5), cancellationToken: ctk); Debug.Log($"{taskIndex}:任务运行中,4/4等待五秒结束,再等20秒"); await UniTask.Delay(TimeSpan.FromSeconds(20), cancellationToken: ctk); } }
如下所示,FlowA脚本继承了MonoBehaviour类,还实现了IFlowAsync的接口
下面是FlowA 的脚本关键代码,那么如何定义一个接口Class呢,见下 5
public class FlowA : MonoBehaviour, IFlowAsync
{
public async UniTask FlowAsync(CancellationToken ctk)
{
Debug.Log($"我是monobehaviourA {Time.realtimeSinceStartup}");
await UniTask.Delay(2000,cancellationToken:ctk);
Debug.Log($"UniTask.Delay(2000) {Time.realtimeSinceStartup}");
}
}
using System.Threading;
using Cysharp.Threading.Tasks;
/// <summary>
/// 接口:定义一个叫FlowAsync的异步方法
/// </summary>
public interface IFlowAsync
{
public UniTask FlowAsync(CancellationToken ctk);
}
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。