之前可能也有群友写过一些关于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. 3.javaweb-servlet

    1. 设置编码 tomcat8之前,设置编码: 1)get请求方式: //get方式目前不需要设置编码(基于tomcat8) //如果是get请求发送的中文数据,转码稍微有点麻烦(tomcat8之前) ...

  2. Caused by: java.lang.NoSuchMethodError

    ERROR [localhost-startStop-1] - Context initialization failedorg.springframework.beans.factory.BeanD ...

  3. WinHex恢复分区

    情景再现:可能在某一天,打开电脑时发现只剩C盘,剩下的盘找不到了,那么要如何恢复呢? 创建虚拟硬盘方便我们做实验 右键计算机 -> 管理 -> 磁盘管理右键 -> 创建VHD虚拟硬盘 ...

  4. 【打怪升级】【rocketMq】rocket的持久化

    rocket持久化保证的思想有两点:1是刷盘保证大部分数据不丢失:2是持久化文件的处理,零拷贝技术和内存页,NIO模型保证处理能力 文件持久化目录 ├──abort:rocket broker启动检查 ...

  5. 等价类计数:Burnside引理和Polya定理 阐述和相关例题

    本人不确保结果正确性. 类似的题集也很多,比如 https://ac.nowcoder.com/acm/contest/27275#question 我做了部分题目的题解 https://www.cn ...

  6. springboot切换web服务器

    <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://mave ...

  7. 中高等DP总结(更新中

    1.CF613D Kingdom and its Cities 题意:给定一棵树,每个询问给出一些关键点,要求删掉最少的点使这些点两两不联通,无解输出-1. 思路:先判无解:只要有一个关键点的父亲也是 ...

  8. GO实现Redis:GO实现TCP服务器(1)

    本文实现一个Echo TCP Server interface/tcp/Handler.go type Handler interface { Handle(ctx context.Context, ...

  9. VUEX面试题

    1.你有写过vuex中store的插件吗? 答:没有 2.你有使用过vuex的module吗?主要是在什么场景下使用? 答:把状态全部集中在状态树上,非常难以维护.按模块分成多个module,状态树延 ...

  10. jQuery绑定方法

    流程/*** * 1.文件命名 * jquery.banner.1.0.0.js * jquery.banner.js * 2.添加匿名函数 * (function(){})() * 3.给插件前后添 ...