ET介绍——单线程异步

这篇具有很好参考价值的文章主要介绍了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文章来源地址https://www.toymoban.com/news/detail-449662.html

到了这里,关于ET介绍——单线程异步的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • ET介绍——浅谈AI框架

    AI在游戏中很多,但是为什么大家总是感觉ai编写起来十分困难,我后来思考了一番,主要原因是使用的方法不当。之前大家编写ai主要有几种方案: 我是不知道谁想出来这个做法的,真是无力吐槽。本来对象身上任何数据都是状态,这种方法又要把一些状态定义成一种新的节

    2024年02月05日
    浏览(37)
  • ET介绍——Actor Location

    Actor模型只需要知道对方的InstanceId就能发送消息,十分方便,但是有时候我们可能无法知道对方的InstanceId,或者是一个Actor的InstanceId会发生变化。这种场景很常见,比如:很多游戏是分线的,一个玩家可能从1线换到2线,还有的游戏是分场景的,一个场景一个进程,玩家从场

    2024年02月05日
    浏览(38)
  • ET介绍——强大的MongoBson库

    后端开发,统计了一下大概有这些场景需要用到序列化: 对象通过序列化反序列化clone 服务端数据库存储数据,二进制 分布式服务端,多进程间的消息,二进制 后端日志,文本格式 服务端的各种配置文件,文本格式 C#序列化库有非常非常多了,protobuf,json等等。但是这些序

    2024年02月05日
    浏览(80)
  • ET介绍—— 一切皆实体的设计

    目前十分流行ECS设计,主要是守望先锋的成功,引爆了这种技术。守望先锋采用了状态帧这种网络技术,客户端会进行预测,预测不准需要进行回滚,由于组件式的设计,回滚可以只回滚某些组件即可。ECS最重要的设计是逻辑跟数据的完全分离。即EC是纯数据,System实际上就

    2024年02月05日
    浏览(31)
  • ET介绍——分布式Actor模型

    在讨论Actor模型之前先要讨论下ET的架构,游戏服务器为了利用多核一般有两种架构,单线程多进程跟单进程多线程架构。两种架构本质上其实区别不大,因为游戏逻辑开发都需要用单线程,即使是单进程多线程架构,也要用一定的方法保证单线程开发逻辑。ET采用的是单线程

    2024年02月05日
    浏览(35)
  • ET介绍——C#更好的协程

    上文讲了一串回调就是协程,显然这样写代码,增加逻辑,插入逻辑非常容易出错。我们需要利用异步语法把这个异步回调的形式改成同步的形式,幸好C#已经帮我们设计好了,看代码   在这段代码里面,WaitTimeAsync方法中,我们利用了TaskCompletionSource类替代了之前传入的Act

    2024年02月05日
    浏览(40)
  • ET介绍——组件式设计(优化版的ECS)

    在代码复用和组织数据方面,面向对象可能是大家第一反应。面向对象三大特性继承,封装,多态,在一定程度上能解决不少代码复用,数据复用的问题。不过面向对象不是万能的,它也有极大的缺陷: 一旦父类中增加或删除某个字段,可能要影响到所有子类,影响到所有子

    2024年02月05日
    浏览(32)
  • ET介绍——更为便捷高效的AI框架-行为机(Behavior Machine)

    顾名思义,类比状态机每个节点是一个状态,行为机每个节点是描述一种行为。行为机每个节点之间是互斥的,并且节点相互之间完全不用关心是怎么切换的。这里就不讲状态机跟行为树是怎么做ai的了,这里只讲用行为机怎么做一个ai。举个例子 mmo中的小怪策划案,大致会

    2024年02月05日
    浏览(39)
  • 线程池创建线程异步获取Future超时

    其中,future.get是从开始进行get方法时进行计算的时间,非future生成开始计算的,即什么时候get什么时候开始计时。 线程池从生成线程,如果核心线程不为0,则有任务时一直生成核心线程,直至到核心线程,之后开始方队列中,最后任务多就开始开辟新线程到最大线程数。

    2024年02月02日
    浏览(37)
  • @Async异步线程:Spring 自带的异步解决方案

            在项目应用中,使用MQ异步调用来实现系统性能优化,完成服务间数据同步是常用的技术手段。如果是在同一台服务器内部,不涉及到分布式系统,单纯的想实现部分业务的异步执行,这里介绍一个更简单的异步方法调用。         对于异步方法调用,从Spring3 开

    2023年04月24日
    浏览(66)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包