Unity中的异步编程【5】——在Unity中使用 C#原生的异步(Task,await,async) - System.Threading.Tasks

news2024/11/24 16:38:45

一、UniTask(Cysharp.Threading.Tasks)和Task(System.Threading.Tasks)的区别

  • 1、System.Threading.Tasks中的Task是.Net原生的异步和多线程包。
  • 2、UniTask(Cysharp.Threading.Tasks)是仿照.Net原生的Task,await,async开发的一个包,该包专门服务于Unity,所以取名UnityTask,简称UniTask。
  • 3、既然有Task了,为啥还要搞一个UniTask
  • (1)Task可以用在PC和Android上,但是在WebGL上则会报错(与多线程的支持有关),你可以退而求其次,使用协程实现异步等待。但是这样容易形成两套代码,增加工作量。
  • (2)UniTask则是用一套代码打天下【一套写法,适用于PC,Android,WebGL等等】,UniTask用协程把await,async统一到多个运行平台。

背景:之前用Unity2020 + UniTask开发的项目,结果用户的需求是要集成到Unity2017.4.37的一个工程文件里面,所有只能返祖了。

二、为Task增加新的功能

  • 1、UniTask有WaitUntil(),而Task没有,只能手动添加一个
/// <summary>
/// 方法:WaitUntil
/// </summary>
/// <param name="predicate">条件语句</param>
/// <param name="sleep">delay事件</param>
/// <returns>Task</returns>
public static async Task WaitUntil(Func<bool> predicate, int sleep = 50)
{
    while (!predicate())
    {
        await Task.Delay(sleep);            
    }
}

  • 2、UniTask有DelayFrame(),而Task没有,手动添加一个
 /// <summary>
 /// 方法:等待X帧
 /// </summary>
 /// <returns>Task</returns>
 public static async Task DelayFrame(int count)
 {
     var current = Time.frameCount;
     while (Time.frameCount - current > count)
     {
         await Task.Yield();
     }
 }
  • 3、UniTask中为多种UI实现了异步点击的方法,在Task模式下,如何为一个Button打造一个异步点击方法——OnClickAsync
  • (1)使用扩展方法来实现
  • (2)给一个button的OnClick绑定一个方法,发生点击事件时,更改一个bool标记
  • (3)用Task的await来循环等待用于标记Button点击的bool标记是否为true
  • (4)取消button上OnClick中之前绑定的方法
  • (5)返回
 /// <summary>
    /// 为Button定制一个扩展方法:点击事件的异步等待
    /// </summary>
    /// <param name="button">按钮Button</param>
    /// <param name="delayMs">循环等待中delay的时间-毫秒</param>
    /// <returns>Task</returns>
    public static async Task OnClickAsync(this Button button,int delayMs = 50)
    {
        bool clicked = false;
        UnityAction ClickAction = () => 
        {
            clicked = true;
            //Debug.Log($"ClickAction() was called {Time.realtimeSinceStartup}");
        };

        //Debug.Log("添加侦听");
        button.onClick.AddListener(ClickAction); //此处不能用兰姆达,不然传入的是临时定义的方法,而不是提前定义的。

        while (!clicked)
        {            
            await Task.Delay(delayMs); //等待时间【ms毫秒】
        }

        //Debug.Log("移除侦听");
        button.onClick.RemoveListener(ClickAction);

        ClickAction = null;
    }

三、代码清单

代码【1】——扩展Task

using System;
using System.Threading.Tasks;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;

/// <summary>
/// Task扩展工具     【System.Threading.Tasks 】
///     not UniTask  【Cysharp.Threading.Tasks】
/// </summary>
public static class TaskUtils
{
    /// <summary>
    /// 方法:WaitUntil
    /// </summary>
    /// <param name="predicate">条件语句</param>
    /// <param name="sleep">delay事件</param>
    /// <returns>Task</returns>
    public static async Task WaitUntil(Func<bool> predicate, int sleep = 50)
    {
        while (!predicate())
        {
            await Task.Delay(sleep);            
        }
    }

    /// <summary>
    /// 方法:等待X帧
    /// </summary>
    /// <returns>Task</returns>
    public static async Task WaitFrame(int count)
    {
        var current = Time.frameCount;
        while (Time.frameCount - current > count)
        {
            await Task.Yield();
        }
    }

    /// <summary>
    /// 方法:等待X帧
    /// </summary>
    /// <returns>Task</returns>
    public static async Task DelayFrame(int count)
    {
        var current = Time.frameCount;
        while (Time.frameCount - current > count)
        {
            await Task.Yield();
        }
    }    
}

【2】——测试Task

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using System.Threading.Tasks;
using System;

/// <summary>
/// 按钮被点击的事件绑定
/// </summary>
public class ButtonClicked : MonoBehaviour {

	public Button myButton;

	// Use this for initialization
	void Start () {

		Func<Task> Flow = async() => 
		{
            while (true)
            {
				Debug.Log($"等待按钮被点击-{Time.realtimeSinceStartup}");
				await myButton.OnClickAsync();
				Debug.Log($"按钮点击完成-{Time.realtimeSinceStartup}");
			}			
		};
		Flow();
	}
}
  • 【3】测试结果
    测试环境Unity2017.4.37 Editor + Win10
    在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/158047.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【C++】继承

​&#x1f320; 作者&#xff1a;阿亮joy. &#x1f386;专栏&#xff1a;《吃透西嘎嘎》 &#x1f387; 座右铭&#xff1a;每个优秀的人都有一段沉默的时光&#xff0c;那段时光是付出了很多努力却得不到结果的日子&#xff0c;我们把它叫做扎根 目录&#x1f449;继承的概…

通俗易懂的java设计模式(6)-代理模式

1.什么是代理模式 为某个对象提供一个代理对象&#xff0c;通过这个代理对象&#xff0c;可以控制对原对象的访问。 通俗的解释&#xff1a;我们电脑桌面上的一个个快接方式&#xff0c;当我们点击这个快捷方式的时候&#xff0c;我们就间接地访问到了这个程序。 2.静态代理…

附录B:Standard Delay Format(SDF)(下)

文章目录B.4 映射实例(Mapping Examples)传播延迟(Propagation Delay)输入建立时间(Input Setup Time)输入保持时间(Input Hold Time)输入建立和保持时间(Input Setup and Hold Time)输入恢复时间(Input Recovery Time)输入撤销时间(Input Removal Time)周期(Period)脉宽(Pulse…

C#自动化物流仓库WMS系统源码

分享一套C#自动化仓库WMS管理系统源码 MF00426 需要源码学习可私信我获取。 WMS作为现代物流系统中的主要组成部分&#xff0c;是一种多层次存放货物的高架仓库系统&#xff0c;由自动控制与管理系统、货架、巷道式堆垛机、出入库输送机等设 备构成&#xff0c;能按指令自动完…

PHP多进程(二)

上篇文章我们说到父进程应该回收子进程结束之后产生的数据,这样才会不浪费系统资源。 一个程序启动之后&#xff0c;变成了一个进程&#xff0c;进程在以下情况会退出 1&#xff09;运行到最后一行语句 2) 运行时遇到return 时 3) 运行时遇到exit()函数的时候 4) 程序异常的时…

【Dash搭建可视化网站】项目13:销售数据可视化大屏制作步骤详解

销售数据可视化大屏制作步骤详解1 项目效果图2 项目架构3 文件介绍和功能完善3.1 assets文件夹介绍3.2 app.py和index.py文件完善3.3 header.py文件完善3.4 api.py文件和api.ipynb文件完善3.4.1 需求数据获取3.4.2 header.py文件中数据变更3.5 middle.py文件完善3.5.1 中间第一…

24.数组名字取地址变成数组指针,数组名和指针变量的区别

数组名字取地址变成数组指针 1.一维数组名字取地址&#xff0c;变成一维数组指针&#xff0c;加1跳一个一维数组。 int a[10]; a1 跳一个整型元素&#xff0c;是a[1]的地址 a和a1相差一个元素&#xff0c;4个字节 &a 就变成了一个一位数组指针&#xff0c;是int(*p)[10]…

结构体重点知识大盘点

0、结构体基础知识 1、结构体是一些值的集合&#xff0c;这些值被称为成员&#xff0c;它们的类型是可以不同的。&#xff08;与数组相似&#xff0c;但数组元素的类型都是相同的&#xff09;。用来描述由基本数据类型组成的复杂类型。 2、结构体也有全局的和局部的。 3、st…

Hello World with VS 17.4.4 DOT NET MAUI Note

Hello World with VS 17.4.4 DOT NET MAUI Note kagula2023-1-12 Prologue If you touched XAML, well here is a concise guide for you running the first MAUI project. Content System Requirement 【1】Microsoft Windows [Version 10.0.19044.2486] Chinese Language …

Ubuntu Centos Linux End Kernel panic-not syncing:Attempted to kill init!

原问题&#xff1a; 当前系统为 Ubuntu 解决问题步骤&#xff1a; 1、重启电脑&#xff0c;在进入选择版本时&#xff0c;选择 系统高级选项&#xff0c; 我选的是【Ubuntu高级选项】 2、进入一个又很多系统版本的界面&#xff0c;每个版本有三个选项&#xff1a;常规启动版…

如何在 ASP.NET Core 2.X 项目中通过EF Core使用MySQL数据库

目录 一、安装MySql.Data.EntityFrameworkCore 二、创建EF Core上下文类以及相关数据模型类 三、配置连接字符串 四、在Starup.cs中注册数据库服务&#xff08;配置Context类的依赖注入&#xff09; 五、通过数据迁移命令生成数据库 目前EF Core已经支持了MySQL数据库了。…

从零开始带你实现一套自己的CI/CD(四)Jenkins Pipeline流水线

目录一、简介二、Groovy2.1 HelloWorld2.2 Pipeline script from SCM三、Jenkinsfile3.1 拉取代码3.2 代码质量检测3.3 构建代码3.4 制作镜像并发布镜像仓库3.5 部署到目标服务器3.6 完整的Jenkinsfile3.7 参数配置3.8 通过参数构建四、添加邮件通知4.1 配置Jenkins邮件配置4.2…

开源飞控初探(一):无人机的历史

这章先纠正大疆带给无人机外行小白的认知。定义无人机无人机的正式英文名字是Unmanned Aerial Vehicle&#xff0c;缩写为UAV。有人无人的区分&#xff0c;是看飞机能否一直需要人为操控。最简单的场景是&#xff0c;当飞机飞出视线之外时&#xff0c;人已经很难实时根据环境来…

微服务自动化管理【docker compose】

1.什么是docker-compose Docker-Compose项目是Docker官方的开源项目&#xff0c;负责实现对Docker容器集群的快速编排 通过编写docker-compose文件可对多个服务同时进行启动/停止/更新(可定义依赖&#xff0c;按顺序启动服务) docker-compose将所管理的容器分为3层结构&#…

Yii2下PHP远程调试PHP5.6/7.2与Xdebug2.5/2.7/3.0 在PHPSTORM下的差异化表现

学习起因&#xff1a;新人学YII2不知道远程调试(远程调试和控制台调试是两件事&#xff0c;同一个原理) 因为yii2框架&#xff0c;设计复杂度非常高&#xff0c;加上php代码的弱类型语言结构&#xff0c;在代码非常复杂的情况下&#xff0c;不采用调试的方式来看源码调用栈&am…

MPLS 虚拟专线 实验

目录 1.拓扑图 2.实验思路 3.主要配置 4.测试 5.实验总结 1.拓扑图 2.实验思路 IGP路由 MPLS Domain 配置MPLS VPN PE之间的MP-BGP邻居关系 CE端与PE端的路由交换 双向重发布&#xff0c;实现路由共享 3.主要配置 R6&#xff1a; *公网环境&#xff1a; [r6]ospf 1 r…

记录robosense RS-LIDAR-16使用过程2

一、安装并使用可视化工具RSView&#xff0c;官网提供了不同版本的安装包&#xff0c;根据个人环境下载解压。本人ubuntu18系统&#xff0c;修改权限&#xff1a;chmod ax run_rsview.sh;然后运行&#xff1a;./run_rsview.sh。该软件每次启动时都要运行./run_rsviewer.sh该软件…

Acwing 1214. 波动数列

题目链接&#xff1a;1214. 波动数列 - AcWing题库 标签&#xff1a;动态规划 &#xff08;字好丑...&#xff09; AC代码&#xff1a; #include<iostream> using namespace std;int f[1005][1005];const int MOD 100000007;//返回正余数 int get_mod(int a,int b) {…

不重复的随机数问题

前言 对于随机数的运用&#xff0c;在开发中经常会用到。有时需要生成不重复的定范围定总量的随机数&#xff0c;比如1~20&#xff0c;需要打乱的1~20中的10个数&#xff0c;那到底怎么做呢? 一、不重复的随机数 我们知道&#xff0c;直接用random会有重复的数字&#xff0…

电商物流云仓的原理是什么?

以云的速度和范围获得胜利  这是一个快速转型时期&#xff0c;封锁、就地避难订单和游览限制扰乱了美国经济的各个范畴&#xff0c;对供给链运营产生了严重影响。在如此动乱的时期&#xff0c;企业正越来越多地转向云优先战略&#xff0c;以使其供给链愈加矫捷和灵敏。  战…