Unity异步编程【6】——Unity中的UniTask如何取消指定的任务或所有的任务

这篇具有很好参考价值的文章主要介绍了Unity异步编程【6】——Unity中的UniTask如何取消指定的任务或所有的任务。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

今天儿童节,犬子已经9个多月了,今天是他的第一个儿童节。中年得子,其乐无穷(音:ku bu kan yan)…回头是岸啊

〇、 示例效果

一连创建5个异步任务[id 从0~4],先停止其中的第id == 4的任务,再停止所有的任务
Unity异步编程【6】——Unity中的UniTask如何取消指定的任务或所有的任务

一、CancellationTokenSource有什么用?

在Unity中,CancellationTokenSource用于创建和控制CancellationToken实例,以便在需要时请求取消异步操作。CancellationToken实例是一种轻量级的结构,用于在异步操作执行期间检查是否已请求取消。

首先,您需要创建一个CancellationTokenSource实例,用于创建和控制CancellationToken实例。然后,将CancellationToken实例传递给您要执行的异步任务,以便在需要时请求取消操作。最后,您可以调用CancellationTokenSource实例的Cancel()方法来请求取消所有使用该CancellationToken的异步操作。

二、cts用法示例

  • 1、定义一个异步任务——它的参数为CancellationToken
public async UniTask FlowAsync(CancellationToken ctk)
    {
        foreach (var script in scripts)
        {
            Debug.Log($"执行步骤:{script.name}");
            await (script as IFlowAsync).FlowAsync(ctk);
        }
    }
  • 2、启动一个cts任务,用于管理FlowAsync任务
    生成一个 cts 实例,TaskSingol的定义见下文《用多个CancellationTokenSource实例来管理多个异步任务管理》
#if UNITY_EDITOR
    [ContextMenu("测试步骤")]
#endif
    void testAsync()
    {
        var ctsInfo = TaskSingol.CreatCts(); //生成一个 cts 实例,TaskSingol的定义见下文《用多个CancellationTokenSource实例来管理多个异步任务管理》
        FlowAsync(ctsInfo.cts.Token);        //传入token  
    }

三、用多个CancellationTokenSource实例来管理多个异步任务管理

  • 定义一个全局的class,用于管理不同异步的cancellation操作
  • 每次启动一个异步任务,都对应一个CancellationTokenSource实例和一个task id
  • 包含功能:
    1、创建一个异步任务
    2、取消所有异步任务
    3、取消指定的异步任务
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());
    }
}

四、凡是异步方法都传入cancellationToken,凡是await的地方,都设置cancellationToken

1、 任务A的monobehaviour脚本

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}");
    }
}

2、 任务B的monobehaviour脚本


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}");
    }
}

3、测试脚本

测试内容:
启动一个任务
停止所有任务
停止指定任务【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);
    }
}

4、如何让所有的脚本都实现一个FlowAsync的方法——实现一个接口

如下所示,FlowA脚本继承了MonoBehaviour类,还实现了IFlowAsync的接口
下面是FlowA 的脚本关键代码,那么如何定义一个接口Class呢,见下 5文章来源地址https://www.toymoban.com/news/detail-471279.html

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}");
    }
}

5、如何让所有的脚本都实现一个FlowAsync的方法——定义一个接口

using System.Threading;
using Cysharp.Threading.Tasks;

/// <summary>
/// 接口:定义一个叫FlowAsync的异步方法
/// </summary>
public interface IFlowAsync
{
    public UniTask FlowAsync(CancellationToken ctk);
}

到了这里,关于Unity异步编程【6】——Unity中的UniTask如何取消指定的任务或所有的任务的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Flutter实现ControlExecutor进行多个异步任务执行时监听状态并可指定最后执行的异步并在指定的异步执行完毕后结束executor并回调。

    1.场景 当有多个接口请求时,且接口调用不是同时进行时,而且接口调用有可能时链式的,中间也有可能加入别的逻辑,但是需要在第一个接口调用时打开等待框,在最后一个接口调用完成时关闭等待框类似需求时,可以用到ControlExecutor进行接口执行过程的监听,并可标记最

    2024年02月09日
    浏览(38)
  • java定时任务如何取消

    java定时任务如何取消,并比如,我之前想每周二晚上6点自动生成一条devops流水线,现在我想停掉 答案: 在Java中,可以使用 ScheduledExecutorService 类来创建定时任务。要取消定时任务,可以调用 ScheduledFuture 对象的 cancel() 方法。 以下是一个示例代码,演示如何创建一个每周二

    2024年02月11日
    浏览(45)
  • JAVA项目中的异步任务

    使用异步任务(Async Task)的主要目的是为了提高程序的响应速度和性能。异步任务允许程序在执行某些耗时操作时,不会阻塞主线程,从而使得主线程能够更快地响应用户的请求,提高用户体验。 实际开发中业务存在不同的任务场景,负责参与业务的任务可能并不是必须顺

    2024年02月08日
    浏览(39)
  • Python异步编程之web框架 异步vs同步 文件IO任务压测对比

    主题: 比较异步框架和同步框架在文件IO操作的性能差异 python版本 :python 3.8 压测工具 :locust web框架 :同步:flask 异步:aiohttp、starlette 异步文件模块 :aiofiles、anyio.Path 请求并发量 : 模拟10个用户 服务器配置 : Intel(R) i7-12700F 客户端配置 :Intel(R) i7-8700 3.20GHz flask是python中轻

    2024年02月06日
    浏览(117)
  • Python异步编程之web框架异步vs同步 无IO任务压测对比

    在python编程中,通过协程实现的异步编程号称能够提高IO密集型任务的并发量。本系列比较web服务器同步框架和异步框架的性能差异,包括无IO接口和常见IO操作,如文件、mysql、redis等。使用压测工具locust测试相同条件下两种编程模式能够处理请求的速度。 主题: 单纯比较异

    2024年02月06日
    浏览(52)
  • Python异步编程之web框架 异步vs同步 数据库IO任务并发支持对比

    主题: 比较异步框架和同步框架在数据库IO操作的性能差异 python版本 :python 3.8 数据库 :mysql 8.0.27 (docker部署) 压测工具 :locust web框架 :同步:flask 异步:starlette 请求并发量 : 模拟10个用户 服务器配置 : Intel(R) i7-12700F 客户端配置 :Intel(R) i7-8700 3.20GHz python中操作数据库通常

    2024年02月08日
    浏览(58)
  • 20230515学习笔记——js中的同步任务与异步任务,宏任务与微任务

    2023-05-15 (1)js中的同步任务与异步任务 ①同步任务是指:不耗时的任务,就是执行很快, ②异步任务是指:耗时的任务,它里面有一个机制是EventLoop(事件循环),即值耗时任务会被js分配到宿主环境中进行执行,执行后的结果放到一个“消息队列”中,当js将同步任务执行完

    2024年02月04日
    浏览(42)
  • Python异步编程之web框架 异步vs同步 数据库IO任务压测对比

    主题: 比较异步框架和同步框架在数据库IO操作的性能差异 python版本 :python 3.8 数据库 :mysql 8.0.27 (docker部署) 压测工具 :locust web框架 :同步:flask 异步:starlette 请求并发量 : 模拟10个用户 服务器配置 : Intel(R) i7-12700F 客户端配置 :Intel(R) i7-8700 3.20GHz python中操作数据库通常

    2024年02月08日
    浏览(93)
  • 前端中的同步和异步任务详细说明

    一、什么是同步/异步任务? 同步任务:指的是在主线程上排队执行的任务,只有当前一个任务执行完毕 才能执行下一个任务(按照顺序执行) 异步任务:指的是不进入主线程上的任务,进入任务队列的任务,只有当任务队列通知主线程某个异步任务可以执行,方可进入主线

    2024年04月26日
    浏览(35)
  • Unity 协程 Unity Task UniTask

    使用 StartCoroutine 和 IEnumerator yield return null 暂停执行并随后在下一帧恢复 yield return new WaitForSeconds(1f); 延迟1秒 waitfor系列有好几个 WaitForSeconds 和 WaitForSecondsRealtime 的区别 使用缩放时间将协程执行暂停指定的秒数。 实际暂停时间等于给定时间除以 Time.timeScale。如果要使用未缩放

    2024年02月08日
    浏览(39)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包