之前可能也有群友写过一些关于ET框架中TimerComponent的使用教程,我这里写下关于TimerComponent的常规使用跟一些不常规使用的方法以及一些情况下需要使用到的不同的函数。

先来看看TimerComponent中都有哪几个方法,

常规的写法,先来个常规计时器,例子放在登录UI中示例,代码如下,此时能发现运行后,登录按钮开始一秒一秒计时,当我们点击登录按钮,此刻服务端返回消息要切换到大厅界面,登录界面销毁,此刻中的协程仍在TimerComponent中缓存,因为等待时间未到的缘故,于是当在时间到了之后,协程里头的执行的给Text赋值,Text已经不存在,此时会报空引用错误。也就是协程没有绑定UI的生命周期。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 定义
private TimerComponent timer = ETModel.Game.Scene.GetComponent();
 
// 计时器方法, 本方法放在UILoginComponent中作为示例
private async void Counter()
{
int count = 0;
while (true)
{
await this.timer.WaitAsync(1000);
loginBtn.GetComponentInChildren().text = $"登录{count}s";
count++;
}
}

此刻我们该怎么解决协程生命周期绑定UI周期这个东东呢? Unity官方的协程Coroutine是绑定MonoBehavior周期的,ET中不适用Mono的情况下,TimerComponent提供了一个CancellationToken方案,可以用于绑定生命周期。下面依旧是定期器为例子,做些修改,调用的方法由WaitAsync(long time)变成WaitAsync(long time, CancellationToken cancellationToken),调用的时候传入一个取消标志,销毁UI的时候调用Cancel就可以把当前不想处理的UI相关的协程从Task池中移除出来。WaitAsync中有个CancellationToken的标志,TimerComponent中注册了Cancel的执行方法,当执行Cancel的时候,TimerComponent中将不会存在关于此CancellationToken的协程

1
2
3
4
5
6
7
8
9
public Task WaitAsync(long time, CancellationToken cancellationToken)
{
TaskCompletionSource tcs = new TaskCompletionSource();
Timer timer = new Timer { Id = IdGenerater.GenerateId(), Time = TimeHelper.Now() + time, tcs = tcs };
this.timers[timer.Id] = timer;
this.timeId.Add(timer.Time, timer.Id);
cancellationToken.Register(() => { this.Remove(timer.Id); });
return tcs.Task;
}

具体区别的代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
// define
private TimerComponent timer = ETModel.Game.Scene.GetComponent();
CancellationTokenSource tokenSource = new CancellationTokenSource();
CancellationToken cancelLogin;
 
// 初始化
public void Awake()
{
ReferenceCollector rc = this.GetParent().GameObject.GetComponent();
loginBtn = rc.Get("LoginBtn");
loginBtn.GetComponent().onClick.Add(OnLogin);
this.account = rc.Get("Account");
this.cancelLogin = (CancellationToken)this.tokenSource.Token;
Counter();
}
 
// 定时器方法调用的区别
private async void Counter()
{
int count = 0;
while (true)
{
await this.timer.WaitAsync(1000, this.cancelLogin);
loginBtn.GetComponentInChildren().text = $"登录{count}s";
count++;
}
}
 
// 从登陆界面跳转大厅界面 的时候,先执行Cancel的方法,将登陆界面的协程从TimerComponent中移除掉,这样就不会抱空引用错误了
private void OnLogin()
{
this.tokenSource.Cancel();
Game.Scene.GetComponent().Create(UIType.UILobby);
Game.Scene.GetComponent().Remove(UIType.UILogin);
}

本文固定链接: http://www.flamesky.xyz/?p=14
转载请注明: Flamesky 2018年04月22日 于 Flamesky 发表

ET–异步协程使用–TimerComponent篇的更多相关文章

  1. 【Python3爬虫】使用异步协程编写爬虫

    一.基本概念 进程:进程是一个具有独立功能的程序关于某个数据集合的一次运行活动.进程是操作系统动态执行的基本单元. 线程:一个进程中包含若干线程,当然至少有一个线程,线程可以利用进程所拥有的资源.线程 ...

  2. 消息/事件, 同步/异步/协程, 并发/并行 协程与状态机 ——从python asyncio引发的集中学习

    我比较笨,只看用await asyncio.sleep(x)实现的例子,看再多,也还是不会. 已经在unity3d里用过coroutine了,也知道是“你执行一下,主动让出权限:我执行一下,主动让出权 ...

  3. python协程与异步协程

    在前面几个博客中我们一一对应解决了消费者消费的速度跟不上生产者,浪费我们大量的时间去等待的问题,在这里,针对业务逻辑比较耗时间的问题,我们还有除了多进程之外更优的解决方式,那就是协程和异步协程.在引入 ...

  4. asyncio模块实现单线程-多任务的异步协程

    本篇介绍基于asyncio模块,实现单线程-多任务的异步协程 基本概念 协程函数 协程函数: 定义形式为 async def 的函数; aysnc 在Python3.5+版本新增了aysnc和awai ...

  5. 深入理解协程(二):yield from实现异步协程

    原创不易,转载请联系作者 深入理解协程分为三部分进行讲解: 协程的引入 yield from实现异步协程 async/await实现异步协程 本篇为深入理解协程系列文章的第二篇. yield from ...

  6. 深入理解协程(三):async/await实现异步协程

    原创不易,转载请联系作者 深入理解协程分为三部分进行讲解: 协程的引入 yield from实现异步协程 async/await实现异步协程 本篇为深入理解协程系列文章的最后一篇. 从本篇你将了解到: ...

  7. python爬虫--多任务异步协程, 快点,在快点......

    多任务异步协程asyncio 特殊函数: - 就是async关键字修饰的一个函数的定义 - 特殊之处: - 特殊函数被调用后会返回一个协程对象 - 特殊函数调用后内部的程序语句没有被立即执行 - 协程 ...

  8. python爬虫---单线程+多任务的异步协程,selenium爬虫模块的使用

    python爬虫---单线程+多任务的异步协程,selenium爬虫模块的使用 一丶单线程+多任务的异步协程 特殊函数 # 如果一个函数的定义被async修饰后,则该函数就是一个特殊的函数 async ...

  9. Python爬虫进阶 | 异步协程

    一.背景 之前爬虫使用的是requests+多线程/多进程,后来随着前几天的深入了解,才发现,对于爬虫来说,真正的瓶颈并不是CPU的处理速度,而是对于网页抓取时候的往返时间,因为如果采用request ...

  10. 异步协程asyncio+aiohttp

    aiohttp中文文档 1. 前言 在执行一些 IO 密集型任务的时候,程序常常会因为等待 IO 而阻塞.比如在网络爬虫中,如果我们使用 requests 库来进行请求的话,如果网站响应速度过慢,程序 ...

随机推荐

  1. Linux拷贝以及赋权

    拷贝     cp -r  /源文件/* 目标文件/&     //&后台运行符 改变权限  sudo chown -R 用户:群组  文件名           // sudo ch ...

  2. C#中字符数组,字节数组和string之间的转化(转)

    原文链接:http://hi.baidu.com/endyli/item/7bf074945de35e1f934f41fe 来源: NDC(NetworkDiskClient)的界面和后台程序之间用S ...

  3. 学习记录--C++继承与派生编程题

    1.设计一个圆类circle和一个桌子类table,另设计一个圆桌类roundtable,它是从前两个类派生出来的 要求输出一个圆桌的高度,面积与颜色等. #include<iostream&g ...

  4. centOS7 + MongoDB 3.6.22 集群搭建 - 切片+副本集 - 个人学习

    因为我是学习这个,所以是安装成功之后自己再记录一下过程,mongodb是重新安装的,参考博客:MongoDB 3.6.9 集群搭建 - 切片+副本集 1. 服务结构介绍 结构图: 结构图解: 1. S ...

  5. Hive 与 HBase 之间的区别和联系

    首先要知道 Hive 和 HBase 两者的区别,我们必须要知道两者的作用和在大数据中扮演的角色 概念 Hive 1.Hive 是 hadoop 数据仓库管理工具,严格来说,不是数据库,本身是不存储数 ...

  6. put、delete、post、get四种传参方式

    PUT: this.$http.put('url', { modifyTime:this.sizeForm.modifyTime, mqttRes:this.sizeForm.mqttRes, udp ...

  7. CTFSHOW-Reverse-刷题记录

    re2 打开初步分析为32位程序,无壳,拖入IDA32分析 找到关键行47-50,分析得出各函数内部的基本作用如图所示 首先进入分析输入后的处理 可以很明显看出,是对输入的字符串进行处理后再操作,因此 ...

  8. pandas之样本操作

    随机抽样,是统计学中常用的一种方法,它可以帮助我们从大量的数据中快速地构建出一组数据分析模型.在 Pandas 中,如果想要对数据集进行随机抽样,需要使用 sample() 函数.sample() 函 ...

  9. 扯下@EventListener这个注解的神秘面纱。

    你好呀,我是歪歪. 前段时间看到同事在项目里面使用了一个叫做 @EventListener 的注解. 在这之前,我知道这个注解的用法和想要达到的目的,但是也仅限于此,其内部工作原理对我来说是一个黑盒, ...

  10. .NET中使用Redis总结——2.项目实战

    接上篇.NET中使用Redis总结 -- 1.Redis搭建 看一些Redis相关资料,.NET 方面ServiceStack.Redis 用的比较多,就直接拿来用了. 在使用过程中经常过出现假死状态 ...