之前可能也有群友写过一些关于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. 在.NET中使用JWT

    1.配置文件添加 //jwt配置文件 "JWT": { "SigningKey": "14fa5f2rrwsg627fs256fdgff2r5rf52 ...

  2. A better jump —— 优化游戏中的跳跃

    之前一提起角色的跳跃,想当然的想法就是:给角色一个向上的初速,然后由Unity的物理系统接管就好了嘛,这样忽略空气摩擦的影响,根据重力加速度,角色向上跳到最高点的时间和由最高点落下的时间相等,不是很合 ...

  3. binder机制分析

    1. binder基本概念 1.1 特点 1)binder 是一种基于C/S通信模式的IPC(Inter_Process Communication). 2)在传输过程中近需要一次copy,为发送添加 ...

  4. IntelliJ IDEA常用插件

    Mybatis Log Plugin安装好插件后,在Tools工具栏中可以看到安装好的插件,点击即可打开相应窗口,在Debug时,相应的Sql语句即可输出到此窗口,方便查看.此插件相当好用,提升开发效 ...

  5. (转)codeblocks 使用研究

    原帖:http://github.tiankonguse.com/blog/2014/10/11/codeblocks-shutcut.html 使用前 使用 codeblocks 前肯定是下载安装 ...

  6. 开源规则引擎——ice:致力于解决灵活繁复的硬编码问题

    背景介绍 业务中是否写了大量的 if-else?是否受够了这些 if-else 还要经常变动? 业务中是否做了大量抽象,发现新的业务场景还是用不上? 是否各种调研规则引擎,发现不是太重就是接入或维护太 ...

  7. 【Visual Leak Detector】在 QT 中使用 VLD(方式三)

    说明 使用 VLD 内存泄漏检测工具辅助开发时整理的学习笔记. 目录 说明 1. 使用前的准备 2. 在 QT 中使用 VLD 2.1 复制 lib 库及头文件 2.2 在项目 .pro 文件中指明路 ...

  8. Hugging News #0324: 🤖️ 黑客松结果揭晓、一键部署谷歌最新大语言模型、Gradio 新版发布,更新超多!

    每一周,我们的同事都会向社区的成员们发布一些关于 Hugging Face 相关的更新,包括我们的产品和平台更新.社区活动.学习资源和内容更新.开源库和模型更新等,我们将其称之为「Hugging Ne ...

  9. MYSQL 最左匹配原则的原理

    https://blog.csdn.net/Andrew_Chenwq/article/details/125242197最左匹配原则最左匹配原则就是指在联合索引中,如果你的 SQL 语句中用到了联合 ...

  10. R数据分析:生存分析的列线图的理解与绘制详细教程

    列线图作为一个非常简单明了的临床辅助决策工具,在临床中用的(发文章的)还是比较多的,尤其是肿瘤预后: Nomograms are widely used for cancer prognosis, p ...