之前可能也有群友写过一些关于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. Selenium协议

    Selenium驱动浏览器使用的协议是什么? JsonWireProtocol 是通过webdriver与remote sever进行通信的web service协议.通过http请求,完成和remo ...

  2. python+appium拉起APP

      1.首先需要完成环境配置: JDK:https://www.cnblogs.com/wenlongma/p/17103062.html: SDK:https://www.cnblogs.com/w ...

  3. 有时候用uniapp写项目时发现,Map组件在安卓真机可以缩放和移动,但是在ios真机就不行

    如果你的地图组件是放到popup组件里,是用弹框打开的,如何ios端不能缩放, 那你一定要看下这个弹框的层级是否比地图层级要高  z-index. 如果高于地图层级,那地图肯定是不能移动和缩放的

  4. 使用ActiveMQ中遇到的端口占用问题

    原Linux虚拟机中安装了ActiveMQ,EMQX.后期使用中主要使用EMQX来实现消息服务,停止了ActiveMQ.但是虚拟机挂起之后,长时间未再使用.近期由于有使用ActiveMQ的需要,而临时 ...

  5. Linux系统mysql免安装版配置指南

    1.下载(/usr/local目录) wget https://dev.mysql.com/get/Downloads/MySQL-5.7/mysql-5.7.32-linux-glibc2.12-x ...

  6. SpringBoot笔记--配置文件分类+yaml相关知识+读取配置文件内容

    配置文件 要是需要使用自己的配置替换默认配置时,需要使用后缀名为application.properties或者application.yml(application.yaml)进行配置 当然,几个文 ...

  7. CF309E 题解

    11:30,过题.12:50,忘记做法. 吃饭时不该看未来日记的,Ynoj 害人不浅(确信). 以上为个人吐槽. 题目大意 不知道题目翻译是个啥...但讨论区有大佬给出了精确的翻译.我改得符合题目背景 ...

  8. java中foreach循环用法详解

    前言 在前面的文章中,千锋壹哥给大家讲解了for.while.do-while三种循环结构,并讲解了如何跳出循环的几种方式,比如break.continue.return等.但是截止到目前,与循环相关 ...

  9. 一文总结你需要的OpenCV操作

    目录 一.OpenCV简介 1.1 OpenCV是什么 1.2 安装及使用 二.图像的基础 2.1 成像原理 2.2 图像格式 2.3 颜色空间 三.OpenCV基础操作 3.1 图像的读取.显示.保 ...

  10. 生产事故-记一次特殊的OOM排查

    入职多年,面对生产环境,尽管都是小心翼翼,慎之又慎,还是难免捅出篓子.轻则满头大汗,面红耳赤.重则系统停摆,损失资金.每一个生产事故的背后,都是宝贵的经验和教训,都是项目成员的血泪史.为了更好地防范和 ...