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

这篇具有很好参考价值的文章主要介绍了Unity中的异步编程【5】——在Unity中使用 C#原生的异步(Task,await,async) - System.Threading.Tasks。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、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文章来源地址https://www.toymoban.com/news/detail-415751.html

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

到了这里,关于Unity中的异步编程【5】——在Unity中使用 C#原生的异步(Task,await,async) - System.Threading.Tasks的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • Unity 中的 async/await:优雅处理异步任务与协程

    内容将会持续更新,有错误的地方欢迎指正,谢谢!   Unity 中的 async/await:优雅处理异步任务与协程Coroutine       TechX 坚持将创新的科技带给世界! 拥有更好的学习体验 —— 不断努力,不断进步,不断探索 TechX —— 心探索、心进取! 助力快速掌握 async/await 异步等待 为初

    2024年02月06日
    浏览(40)
  • promise及异步编程async await

    ECMAScript 6 新增了正式的 Promise(期约)引用类型,支持优雅地定义和组织异步逻辑。接下来几个版本增加了使用 async 和 await 定义异步函数的机制 JavaScript 是单线程事件循环模型。异步行为是为了优化因计算量大而时间长的操作,只要你不想为等待某个异步操作而阻塞

    2024年02月04日
    浏览(28)
  • C#异步方法async/await的三种返回类型

    有群友问C#异步方法async返回值Task和void的区别?看似简单,但不容易把它们用好。在C#中的异步编程已经成为现代编程的标配,异步方法(async/await)是实现异步编程的一种常用方式。在异步方法中,可以使用 Task 或 void 作为返回类型,还可以使用ValueTask返回类型。本文将介绍

    2024年02月04日
    浏览(31)
  • 前端面试:【异步编程】Callback、Promise和Async/Await

    嗨,亲爱的JavaScript探险家!在JavaScript开发的旅程中,你会经常遇到异步编程的需求。为了处理异步操作,JavaScript提供了多种机制,包括Callbacks、Promises和Async/Await。本文将深入介绍这些机制,让你能够更好地处理异步任务。 1. Callbacks:传统的异步方式 Callbacks是JavaScript中最早

    2024年02月11日
    浏览(32)
  • 异步编程的概念 以及async和await的工作原理

    一、引言 二、异步编程的基本概念 三、基于任务的异步模式(TAP) 四、async和await async的工作原理: await的工作原理: 五、异步方法的编写和调用 六、异常处理 七、取消异步操作 八、性能考虑 九、案例:异步下载文件 十、结论 在.NET中,异步编程是一

    2024年04月16日
    浏览(32)
  • 前端异步编程全套:xmlhttprequest > ajax > promise > async/await

    同步与异步区别 同步:按顺序,依次执行,向服务器发送请求--客户端做其他操作 异步:分别执行,向服务器发送请求==同时执行其他操作 原生xmlhttprequest 四步骤 创建ajax对象 设定数据的传输方式(get、post),打开连接open() 获得响应数据 属性 描述 onreadystatechange 当readysta

    2024年02月01日
    浏览(33)
  • 深入理解Async/Await:从原理到实践的JavaScript异步编程指南

    理解 async/await 的原理和使用方法是理解现代JavaScript异步编程的关键。这里我会提供一个详细的实例,涵盖原理、流程、使用方法以及一些注意事项。代码注释会尽量详尽,确保你理解每个步骤。 实例:使用async/await进行异步操作 详细解释和注释: 异步函数定义: async func

    2024年02月05日
    浏览(44)
  • 一盏茶的功夫帮你彻底搞懂JavaScript异步编程从回调地狱到async/await

     🎬 江城开朗的豌豆 :个人主页  🔥  个人专栏   :《 VUE 》 《 javaScript 》 ⛺️  生活的理想,就是为了理想的生活 ! 目录 📘 1. 引言 📘 2. 使用方法 📘 3. 实现原理 📘 4. 写到最后   在深入讨论 async/await 之前,我们需要了解一下 JavaScript 的单线程和非阻塞的特性。

    2024年02月08日
    浏览(32)
  • 微信小程序——异步请求使用async/await实现同步

            在小程序的开发中,我们知道网络请求wx.requset是一个异步请求的API,当我们使用它时,会出现请求还没有结束,我们下面写的处理数据的代码就已经执行了从而导致了我们写的程序出现问题,那么我们该怎么解决这个问题呢?今天我们用async/await来实现一下吧。

    2024年02月11日
    浏览(30)
  • 详解async 与 await,带您理解Playwright使用异步方法的正确姿势!

    大家在使用python做playwright自动化测试的过程中,一定会发现下面这种异步用法 很多同学可能只是按照这种写法来编写项目的自动化测试代码,对于具体细节可能并不了解,今天我就来讲一下playwright异步用法的相关技术细节。建议大家拷贝文档中的脚本实际运行一下,学习的

    2024年02月12日
    浏览(36)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包