单线程异步

前面几个例子都是多线程实现的异步,但是异步显然不仅仅是多线程的。我们在之前的例子中使用了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介绍——单线程异步的更多相关文章

  1. 【Python】迭代器、生成器、yield单线程异步并发实现详解

    转自http://blog.itpub.net/29018063/viewspace-2079767 大家在学习python开发时可能经常对迭代器.生成器.yield关键字用法有所疑惑,在这篇文章将从 ...

  2. tornado原理介绍及异步非阻塞实现方式

    tornado原理介绍及异步非阻塞实现方式 以下内容根据自己实操和理解进行的整理,欢迎交流~ 在tornado的开发中,我们一般会见到以下四个组成部分. ioloop: 同一个ioloop实例运行在一 ...

  3. JS定时器和单线程异步特性

    首先要说的是,定时器相关的方法都是属于BOM方法,而定时器呢,它是用于在设定的时间执行一段代码,或者在给定的时间间隔内重复该代码.具体函数: setTimeout(callback, delay);/ ...

  4. 单线程异步回调机制的缺陷与node的解决方案

    一.node单线程异步的缺陷: 单线程异步的优点自然不必多说,node之所以能够如此快的兴起,其单线程异步回调机制相比于传统同步执行编程语言的优势便是原因之一.然而,开发一个node程序,其缺陷也是不 ...

  5. node 单线程异步非阻塞

    链接:http://www.runoob.com/nodejs/nodejs-callback.html 首先什么是单线程异步非阻塞? 单线程的意思整个程序从头到尾但是运用一个线程,程序是从上往下执行 ...

  6. js 单线程 异步

    线程与进程: 进程是系统资源分配和调度的单元.一个运行着的程序就对应一个进程.在windows中,每一个打开的运行的应用程序或后台程序,比如运行中的qq,谷歌浏览器,网易云音乐,资源管理器等都是一个进 ...

  7. 爬虫基础--IO多路复用单线程异步非阻塞

    最近一直的学习爬虫  ,进行基础的学习 性能相关 参考 https://www.cnblogs.com/wupeiqi/p/6229292.html # 目标:单线程实现并发HTTP请求 # # so ...

  8. android:异步任务asyncTask介绍及异步任务下载图片(带进度条)

    为什么要用异步任务? 在android中仅仅有在主线程才干对ui进行更新操作.而其他线程不能直接对ui进行操作 android本身是一个多线程的操作系统,我们不能把全部的操作都放在主线程中操作 .比方 ...

  9. Python网络编程中的服务器架构(负载均衡、单线程、多线程和同步、异步等)

    这篇文章主要介绍服务器架构. 网络服务需要面对两个挑战. 第一个问题是核心挑战,要编写出能够正确处理请求并构造合适响应的代码. 第二个挑战是如何将网络代码部署到随系统自动启动的Windows服务或者是 ...

  10. 重回博客 谈一谈Node中的异步和单线程

    重回博客,这个帐号之前注册后就只发了一篇博客.听朋友建议,决定一周两次更新. 第一篇谈论一下最近想的比较多的异步的问题. 传统多线程异步 传统的异步是多线程的,当要同时做两件事的时候,他们是执行在不同 ...

随机推荐

  1. 【LeetCode二叉树#11】最大二叉树(构造二叉树)

    最大二叉树 力扣题目地址(opens new window) 给定一个不含重复元素的整数数组.一个以此数组构建的最大二叉树定义如下: 二叉树的根是数组中的最大元素. 左子树是通过数组中最大值左边部分构 ...

  2. ZYNQ核心板及其底板开源啦!

    Hello-FPGA ZYNQ 设计开源啦! 开源ZYNQ核心板 + 底板 硬件设计.软件设计,软件设计使用裸机演示,演示了如何使用AXI DMA等关键dma 模块 欢迎加QQ 讨论 94755958 ...

  3. MIG是如何向DDR中写入数据的

    1.1    先来看看信号线的描述 我们以X16的器件为例,下面的截图来自 镁光的官方手册 https://media-www.micron.com/-/media/client/global/doc ...

  4. 【Azure Fabric Service】Service Fabric 遇见错误信息记录 - The process/container terminated with exit code:2148734499

    问题描述 Service Fabric 在升级 Application 过程中,发布了新的代码后,启动应用中遇见了如下错误: Error message: System.Hosting' report ...

  5. .NET开源功能强大的串口调试工具

    前言 今天大姚给大家分享一款.NET开源的.功能强大的串口调试工具:LLCOM. 工具介绍 LLCOM是一个.NET开源的.功能强大的串口调试工具.支持Lua自动化处理.串口调试.串口监听.串口曲线. ...

  6. Advanced .Net Debugging 3:基本调试任务(上)

    一.简介 这是我的<Advanced .Net Debugging>这个系列的第三篇文章.这个系列的每篇文章写的周期都要很长,因为每篇文章都是原书的一章内容(太长的就会分开写).再者说,原 ...

  7. RocketMQ(1) 基础介绍和单机-集群安装

    1. MQ简单介绍 1.1 应用场景 应用解耦 系统的耦合性越高,容错性就越低.以电商应用为例,用户创建订单后,如果耦合调用库存系统.物流系统.支付系统,任何一个子系统出了故障或者因为升级等原因暂时不 ...

  8. 排查 dotNET Core 程序内存暴涨的问题

    0. 问题 新版本上线之后,发现内存猛涨,入站流量猛增,不清楚具体原因,部分接口提示 OOM 异常,随后 Pod 直接崩溃无限重启. 1. 准备 Pod 已经接入了 NewRelic 和 Graylo ...

  9. MP实现ID自增 &日志 &自动填充 & 逻辑删除 &乐观锁

    默认ID自增 mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl 此时的依赖 <dep ...

  10. moviepy 官方网址

    https://zulko.github.io/moviepy/ Gitee 说我有违规信息 醉了 { title: "moviepy", url: "https://z ...