单线程异步

前面几个例子都是多线程实现的异步,但是异步显然不仅仅是多线程的。我们在之前的例子中使用了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. 如何编写一个 PowerShell 脚本

    PowerShell 脚本的后缀是 .ps1 前提: ps1 脚本可以帮忙我们快速修改文件内容,还不需要调用文件的底层 api,方便快捷 在编写 CMakeLists 时发现,项目不能够很好的使用 v ...

  2. 【Filament】Filament环境搭建

    1 前言 ​ Filament 是一个实时物理渲染引擎,用于 Android.iOS.Linux.macOS.Windows 和 WebGL 平台.该引擎旨在提供高效.实时的图形渲染,并被设计为在 A ...

  3. redis 安装的参考文章

    redis 安装  :  https://www.runoob.com/redis/redis-install.html

  4. C#的托盘窗体显示与隐藏效果 - 开源研究系列文章

    今天无聊,进行的C#的编码内容仍然在继续.这些天不断地在完善及编写C#的Winform相关的代码,并将其整理形成博文.这次带来的是关于窗体的显示及隐藏效果的代码段.上次有过一个代码,这次当做新代码进行 ...

  5. 安卓插耳机也外放扬声器播放音频的java代码

    最近遇到一个如何在耳机插入的情况下任然用扬声器播放音频的问题. 用搜索引擎找了一些网上的demo(案例) .发现按照他们的方法成功实现. 插入耳机的时候也可以选择使用扬声器播放音乐,来电铃声就是这么用 ...

  6. .NET Conf China 2023济南站社区活动

     2024年3月3日,在这个春暖花开的日子里,由微软MVP项目.山东财经大学管理科学与工程学院.胶东开发者社区.济南.NET俱乐部联合举办了[.NET Conf China 2023 JiNan Wa ...

  7. 深入浅出Java多线程(十一):AQS

    引言 大家好,我是你们的老伙计秀才!今天带来的是[深入浅出Java多线程]系列的第十一篇内容:AQS(AbstractQueuedSynchronizer).大家觉得有用请点赞,喜欢请关注!秀才在此谢 ...

  8. 通过 TCPView KPKIService.exe 删掉 (原来是单点登录的中间件)

    叫 统一安全中间件,就是个第三方做的key的安全检查,谁知道是哪年装的 (原来是单点登录的中间件) 资料 https://baijiahao.baidu.com/s?id=17173842191483 ...

  9. vscode 自动格式化md文件,搞得很是郁闷,加入 [markdown] 自定义配置 "editor.formatOnSave": false 搞定了。

    上下文: vscode做vue的项目开发,需要对代码进行格式化,用的vetur插件 正常来讲,代码保存的时候,需要进行格式化,所以配置文件会写成 "editor.formatOnSave&q ...

  10. C#中的JSON序列化方法

    在C#中的使用JSON序列化及反序列化时,推荐使用Json.NET--NET的流行高性能JSON框架,当然也可以使用.NET自带的 System.Text.Json(.NET5).DataContra ...