UniTask使用笔记

异步处理&同步处理

同步处理:简单说就是代码按顺序执行,在方法1里调用方法2时,要等到方法2执行完毕才接着执行方法1的代码。
异步处理:简单说就是在两个方法里的代码同时或者来回执行,在方法1里调用方法2时,不等方法2执行完就接着执行接下来的代码。

异步不等于多线程

异步处理不等于多线程,因为即使是单线程,也可以通过切换执行的代码来实现异步。典型的例子就是unity的协程。协程就是只运行在主线程来实现异步处理的。
而C#里真正跟多线程相关的是把ThreadPool封装后的Task类。Task类通常通过async/await 来实现异步,但异步和多线程是两个不同的概念。

async/await 和 Task

这两个关键字是C#5.0引进的,本质是由编译器提供的语法糖,来方便进行异步编程用的。对于unity开发者来说,可以看成一个升级版的协程。

//协程版等待一秒
	IEnumerator DelayCoroutine()
    {
   
        Debug.Log("Start");
        yield return new WaitForSeconds(1f);
        Debug.Log("End");
    }
//Async版等待一秒
	async void DelayTask()
    {
   
        Debug.Log("Start");
        await Task.Delay(1000);
        Debug.Log("End");
    }
async/await 与 Coroutine 相比的优点
  1. 由于是C#提供的功能,所以在非Mono脚本里也能实现异步。
  2. 可以方便的拿到异步的返回值。
//异步方法,会在最后返回一个string
async Task<string> DelayTask()
    {
   
        Debug.Log("Start");
        await Task.Delay(1000);
        Debug.Log("End");
        return "Completed";
    }

由于async可以在任何方法前加,同理适用于unity的生命周期函数。

async void Start()
    {
   
        var task = DelayTask();
        Debug.Log("异步执行中..");
        var str = await task;//等待异步结果
        Debug.Log(str);
    }
  1. 避免回调地狱
    有的时候我们希望在执行完异步操作时执行一个回调方法,但如果这个回调也有异步操作也要回调,就会造成回调的嵌套,降低代码的可读性。
    协程的话可以将各个回调做成一个个小协程,之后在一个主协程里yield return。但是由于协程无法返回值,导致如果想要用上一个协程计算出的值的话,只能将回调作为委托传进去,无法避免回调的嵌套。
    但async/await是可以返回值的,可以把回调改写成await的顺序执行。
 async void Start()
    {
   
        var task = DelayTask();
        Debug.Log($"异步执行中..");
        var str = await task;//等待异步结果
        var task2 = AsyncFun2(str);//利用第一个结果执行第二个异步方法
        Debug.Log($"异步执行中..");
        str = await task2();//等待第二个异步结果
        Debug.Log(str);
    }

4.async/await是可以用Try-Catch捕获异常,协程不行。

task 取消的问题

async/await需要明确地取消正在执行的异步方法,比较麻烦。
由于async/await异步实现是依靠着Task实例。Task实例是有可能是多线程的,由于线程是操作系统层面的资源就导致无法直接停止一个Task。所以我们只能做一个公共变量,task在执行异步时不断检查这个变量是否改变,改变的话说明要停止执行,在Task内部自己停止。
C#提供一个“取消标记”叫做CancellationTokenSource.Token,在创建task的时候传入此参数,就可以将主线程和任务相关联,然后在任务中设置“取消信号“叫做ThrowIfCancellationRequested来等待主线程使用Cancel来通知,一旦cancel被调用。task将会抛出OperationCanceledException来中断此任务的执行,最后将当前task的Status的IsCanceled属性设为true。
注意:一定要处理这个异常,可以通过调用Task.Result成员来获取这个异常。如果一直不查询Task的Exception属性。你的代码就永远注意不到这个异常的发生,如果不能捕捉到这个异常,垃圾回收时,抛出AggregateException,进程就会立即终止,这就是“牵一发动全身”,莫名其妙程序就自己关掉了,谁也不知道这是什么情况。所以,必须调用前面提到的某个成员,确保代码注意到异常,并从异常中恢复。因此可以将调用Task的某个成员来检查Task是否跑出了异常,通常调用Task的Result。
而协程只要把调用这个协程的GameObject删了就会停止协程。或者在开启协程时记下协程实例,要取消时调用StopCoroutine(coroutine)就行。主要原因就是await可以返回值,如果中途取消,就可能导致后面的代码异常,所以只能抛异常。

UniTask

虽然在Unity(2017版本以上)中可以正常地使用async/await和Task类,但是C#自带地Task类过于繁重而且一些unity里常用的功能要自己实现和封装。于是CySharp公司推出了UniTask来解决这个痛点。
用UniTask有以下优点:

  1. 用法和和原先的Task类用法一致。(Task-Like)
  2. 比Task更轻量,占用内存少。
  3. 对async/await 的优化,实现大幅减少GC。
  4. 提供unity相关的功能。
  5. 提供各种Awaiter。
  6. 实现在editor下await状态的可视化。(利用UniTaskTracker)

但对Unity版本有要求,需要使用Unity2018.3以上版本。
对同一个UniTask实例不能两次await,不然会报错。

生成UniTask实例的方法
  1. 利用async/await 同C#的用法一样,只不过是将返回值改成相应的UniTask的结构体。
    Task ——> UniTask
    Task<T> ——> UniTask<T>
    void ——> UniTaskVoid //用于不需要返回UniTask的异步方法

  2. 利用UniTaskCompletionSource创建
    用法如下:

async void Start()
    {
   
        var source = new UniTaskCompletionSource();
        ReadyForCompleted(source).Forget();//只引发不考虑其是否完成
        Debug.Log("Do Something...");
        source.TrySetResult();//设置完成
        //source.TrySetException(Exception);//设置失败
        //source.TrySetCanceled();//设置取消
        Debug.Log("Completed");
    }
async UniTask ReadyForCompleted(UniTask
  • 45
    点赞
  • 155
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
当然,我可以为您提供关于Wireshark的使用笔记。下面是一些基本的使用说明: 1. 下载和安装:您可以从Wireshark官方网站(https://www.wireshark.org)下载适用于您操作系统的最新版本,并按照安装向导进行安装。 2. 打开Wireshark:安装完成后,打开Wireshark应用程序。在Windows上,您可以在开始菜单中找到它;在Mac上,您可以在启动台中找到它。 3. 选择网络接口:在Wireshark界面的主窗口中,选择要捕获数据包的网络接口。您可以从列表中选择一个接口,并点击“开始”按钮开始捕获数据包。 4. 捕获数据包:Wireshark将开始捕获选定网络接口上的数据包。您将看到一个实时的数据包列表,显示每个数据包的详细信息。 5. 分析数据包:您可以通过单击数据包来查看其详细信息,包括源地址、目标地址、协议等。Wireshark还提供了各种过滤和排序选项,以帮助您更好地分析数据包。 6. 应用过滤器:Wireshark支持使用过滤器来仅显示您感兴趣的数据包。您可以在“过滤器”框中输入过滤条件,并点击“应用”按钮来应用过滤器。 7. 保存和导出数据包:如果您想保存捕获的数据包以供后续分析,可以使用Wireshark的“保存”选项。您还可以导出捕获的数据包为其他格式,如PCAP、CSV等。 这是一些Wireshark的基本使用笔记,希望对您有所帮助。如果您有任何进一步的问题,请随时提问!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值