ET介绍——单线程异步
单线程异步
前面几个例子都是多线程实现的异步,但是异步显然不仅仅是多线程的。我们在之前的例子中使用了Sleep来实现时间的等待,每一个计时器都需要使用一个线程,会导致线程切换频繁,这个实现效率很低,平常是不会这样做的。一般游戏逻辑中会设计一个单线程的计时器,我们这里做一个简单的实现,用来讲解单线程异步。
// example2_3
class Program
{
private static int loopCount = 0; private static long time;
private static Action action; static void Main(string[] args)
{
Console.WriteLine($"主线程: {Thread.CurrentThread.ManagedThreadId}"); Crontine(); while (true)
{
Thread.Sleep(1); CheckTimerOut(); ++loopCount;
if (loopCount % 10000 == 0)
{
Console.WriteLine($"loop count: {loopCount}");
}
}
} private static void Crontine()
{
WaitTimeAsync(5000, WaitTimeAsyncCallback1);
} private static void WaitTimeAsyncCallback1()
{
Console.WriteLine($"当前线程: {Thread.CurrentThread.ManagedThreadId}, WaitTimeAsync finsih loopCount的值是: {loopCount}");
WaitTimeAsync(4000, WaitTimeAsyncCallback2);
} private static void WaitTimeAsyncCallback2()
{
Console.WriteLine($"当前线程: {Thread.CurrentThread.ManagedThreadId}, WaitTimeAsync finsih loopCount的值是: {loopCount}");
WaitTimeAsync(3000, WaitTimeAsyncCallback3);
} private static void WaitTimeAsyncCallback3()
{
Console.WriteLine($"当前线程: {Thread.CurrentThread.ManagedThreadId}, WaitTimeAsync finsih loopCount的值是: {loopCount}");
} private static void CheckTimerOut()
{
if (time == 0)
{
return;
}
long nowTicks = DateTime.Now.Ticks / 10000;
if (time > nowTicks)
{
return;
} time = 0;
action.Invoke();
} private static void WaitTimeAsync(int waitTime, Action a)
{
time = DateTime.Now.Ticks / 10000 + waitTime;
action = a;
}
}
这个例子同样实现了一个简单的计时方法,WaitTimeAsync调用时会将回调方法跟时间记录下来,主线程每帧都会调用CheckTimerOut,CheckTimerOut里面判断计时器是否过期,过期了则调用回调方法。整个逻辑都在主线程中完成,同样是异步方法。所以异步并非多线程,单线程同样可以异步。上面的例子同样可以改成await的形式。
// example2_3_2
class Program
{
private static int loopCount = 0; private static long time;
private static TaskCompletionSource<bool> tcs; static void Main(string[] args)
{
Console.WriteLine($"主线程: {Thread.CurrentThread.ManagedThreadId}"); Crontine(); while (true)
{
Thread.Sleep(1); CheckTimerOut(); ++loopCount;
if (loopCount % 10000 == 0)
{
Console.WriteLine($"loop count: {loopCount}");
}
}
} private static async void Crontine()
{
await WaitTimeAsync(5000);
Console.WriteLine($"当前线程: {Thread.CurrentThread.ManagedThreadId}, WaitTimeAsync finsih loopCount的值是: {loopCount}");
await WaitTimeAsync(4000);
Console.WriteLine($"当前线程: {Thread.CurrentThread.ManagedThreadId}, WaitTimeAsync finsih loopCount的值是: {loopCount}");
await WaitTimeAsync(3000);
Console.WriteLine($"当前线程: {Thread.CurrentThread.ManagedThreadId}, WaitTimeAsync finsih loopCount的值是: {loopCount}");
} private static void CheckTimerOut()
{
if (time == 0)
{
return;
}
long nowTicks = DateTime.Now.Ticks / 10000;
if (time > nowTicks)
{
return;
} time = 0;
tcs.SetResult(true);
} private static Task WaitTimeAsync(int waitTime)
{
TaskCompletionSource<bool> t = new TaskCompletionSource<bool>();
time = DateTime.Now.Ticks / 10000 + waitTime;
tcs = t;
return t.Task;
}
}
上面这个例子所有调用全部在主线程中完成,并且使用了await,因此await并不会开启多线程,await具体用没用多线程完全取决于具体的实现
ET开源地址地址:egametang/ET: Unity3D Client And C# Server Framework (github.com) qq群:474643097
ET介绍——单线程异步的更多相关文章
- 【Python】迭代器、生成器、yield单线程异步并发实现详解
转自http://blog.itpub.net/29018063/viewspace-2079767 大家在学习python开发时可能经常对迭代器.生成器.yield关键字用法有所疑惑,在这篇文章将从 ...
- tornado原理介绍及异步非阻塞实现方式
tornado原理介绍及异步非阻塞实现方式 以下内容根据自己实操和理解进行的整理,欢迎交流~ 在tornado的开发中,我们一般会见到以下四个组成部分. ioloop: 同一个ioloop实例运行在一 ...
- JS定时器和单线程异步特性
首先要说的是,定时器相关的方法都是属于BOM方法,而定时器呢,它是用于在设定的时间执行一段代码,或者在给定的时间间隔内重复该代码.具体函数: setTimeout(callback, delay);/ ...
- 单线程异步回调机制的缺陷与node的解决方案
一.node单线程异步的缺陷: 单线程异步的优点自然不必多说,node之所以能够如此快的兴起,其单线程异步回调机制相比于传统同步执行编程语言的优势便是原因之一.然而,开发一个node程序,其缺陷也是不 ...
- node 单线程异步非阻塞
链接:http://www.runoob.com/nodejs/nodejs-callback.html 首先什么是单线程异步非阻塞? 单线程的意思整个程序从头到尾但是运用一个线程,程序是从上往下执行 ...
- js 单线程 异步
线程与进程: 进程是系统资源分配和调度的单元.一个运行着的程序就对应一个进程.在windows中,每一个打开的运行的应用程序或后台程序,比如运行中的qq,谷歌浏览器,网易云音乐,资源管理器等都是一个进 ...
- 爬虫基础--IO多路复用单线程异步非阻塞
最近一直的学习爬虫 ,进行基础的学习 性能相关 参考 https://www.cnblogs.com/wupeiqi/p/6229292.html # 目标:单线程实现并发HTTP请求 # # so ...
- android:异步任务asyncTask介绍及异步任务下载图片(带进度条)
为什么要用异步任务? 在android中仅仅有在主线程才干对ui进行更新操作.而其他线程不能直接对ui进行操作 android本身是一个多线程的操作系统,我们不能把全部的操作都放在主线程中操作 .比方 ...
- Python网络编程中的服务器架构(负载均衡、单线程、多线程和同步、异步等)
这篇文章主要介绍服务器架构. 网络服务需要面对两个挑战. 第一个问题是核心挑战,要编写出能够正确处理请求并构造合适响应的代码. 第二个挑战是如何将网络代码部署到随系统自动启动的Windows服务或者是 ...
- 重回博客 谈一谈Node中的异步和单线程
重回博客,这个帐号之前注册后就只发了一篇博客.听朋友建议,决定一周两次更新. 第一篇谈论一下最近想的比较多的异步的问题. 传统多线程异步 传统的异步是多线程的,当要同时做两件事的时候,他们是执行在不同 ...
随机推荐
- 玩转SpringBoot:动态排除Starter配置,轻松部署
引言 在软件开发中,进行本地单元测试是一项常规且必要的任务.然而,在进行单元测试时,有时需要启动一些中间件服务,如Kafka.Elasticjob等.举例来说,我曾经遇到过一个问题:项目中使用了Red ...
- 2019年在浏览器用原生js写WebGL,绘制图形;
因为JavaScript高级程序设计(第三版)中的运行书上15.3WebGL部分的代码时在chrome和firefox浏览器下报错,在后面我网上初步找了一圈,好像没人做出真正可以用的代码;所以我就自己 ...
- 硬件开发笔记(九): 硬件开发基本流程,制作一个USB转RS232的模块(八):创建asm1117-3.3V封装库并关联原理图元器件
前言 有了原理图,可以设计硬件PCB,在设计PCB之间还有一个协同优先动作,就是映射封装,原理图库的元器件我们是自己设计的.为了更好的表述封装设计过程,本文描述了一个创建asm1117-3.3V封 ...
- 硬件开发笔记(二):硬件开发基本流程,制作一个USB转RS232的模块(一):开发基本过程和元器件选型
前言 做个usb转串口,同时兼容ttl,讲述硬件模块基础的开发流程,本篇描述了全流程过程,然后选型了合适的元器件. 基本流程 以下是笔者个人从事过相关硬件研发,总结出来的流程,仅代表个人意 ...
- 公司官网建站笔记(二):在云服务器部署PHP服务(公网访问首页)
前言 上一篇重新安装了CentOS8.2之后,接下来开始安装部署PHP服务器,让公网可以访问到我们部署的PHP服务器首页. 背景 为什么自行搭建,是因为红胖子专业做相关Qt软件以及终端设备 ...
- [Rust] Workspace,Package, Crate 和 Module
package(包) 一个 package 对应一个项目,package 的信息在 Cargo.toml 里面定义. crate(木箱.箱子) crate 指的是 package 编译后的输出文件.以 ...
- Centos下git pull免密码操作
在终端输入以下指令: git config --global credential.helper store然后再次执行pull操作,还是会提示一次输入帐号与密码.断开终端链接,重连,再次进行pull ...
- C#多线程(9):多阶段并行线程
目录 前言 Barrier 类 属性和方法 示例 新的示例 说明 前言 这一篇,我们将学习用于实现并行任务.使得多个线程有序同步完成多个阶段的任务. 应用场景主要是控制 N 个线程(可随时增加或减少执 ...
- 探索Terraform实践:优化基础设施管理
Terraform 是管理基础设施及代码(IaC)最常用的工具之一,它能使我们安全且可预测地对基础设施应用更改. Terraform作为一个强大的基础设施即代码工具,为开发人员和运维团队提供了一种简单 ...
- ChatGPT用10秒画完一张UML流程图,而我用了。。。
不用AI的程序员,失业潮真的快来临了. 一张订单履约的流程图,我花了10分钟才完成,而ChatGPT绘图过程只用了10秒钟,基本可以达到同样的水平,通过ChatGPT可以显著提高画流程图的效率. 订单 ...