ET介绍——C#更好的协程

这篇具有很好参考价值的文章主要介绍了ET介绍——C#更好的协程。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

更好的协程

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

// example2_2
    class Program
    {
        private static int loopCount = 0;
        
        static void Main(string[] args)
        {
            OneThreadSynchronizationContext _ = OneThreadSynchronizationContext.Instance;

            Console.WriteLine($"主线程: {Thread.CurrentThread.ManagedThreadId}");
            
            Crontine();
            
            while (true)
            {
                OneThreadSynchronizationContext.Instance.Update();
                
                Thread.Sleep(1);
                
                ++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 Task WaitTimeAsync(int waitTime)
        {
            TaskCompletionSource<bool> tcs = new TaskCompletionSource<bool>();
            Thread thread = new Thread(()=>WaitTime(waitTime, tcs));
            thread.Start();
            return tcs.Task;
        }
        
        /// <summary>
        /// 在另外的线程等待
        /// </summary>
        private static void WaitTime(int waitTime, TaskCompletionSource<bool> tcs)
        {
            Thread.Sleep(waitTime);
            
            // 将tcs扔回主线程执行
            OneThreadSynchronizationContext.Instance.Post(o=>tcs.SetResult(true), null);
        }
    }

 

在这段代码里面,WaitTimeAsync方法中,我们利用了TaskCompletionSource类替代了之前传入的Action参数,WaitTimeAsync方法返回了一个Task类型的结果。WaitTime中我们把action()替换成了tcs.SetResult(true),WaitTimeAsync方法前使用await关键字,这样可以将一连串的回调改成同步的形式。这样一来代码显得十分简洁,开发起来也方便多了。

这里还有个技巧,我们发现WaitTime中需要将tcs.SetResult扔回到主线程执行,微软给我们提供了一种简单的方法,参考example2_2_2,在主线程设置好同步上下文,

// example2_2_2
SynchronizationContext.SetSynchronizationContext(OneThreadSynchronizationContext.Instance);

 

在WaitTime中直接调用tcs.SetResult(true)就行了,回调会自动扔到同步上下文中,而同步上下文我们可以在主线程中取出回调执行,这样自动能够完成回到主线程的操作

        private static void WaitTime(int waitTime, TaskCompletionSource<bool> tcs)
        {
            Thread.Sleep(waitTime);

            tcs.SetResult(true);
        }

 

如果不设置同步上下文,你会发现打印出来当前线程就不是主线程了,这也是很多第三方库跟.net core内置库的用法,默认不回调到主线程,所以我们使用的时候需要设置下同步上下文。其实这个设计本人觉得没有必要,交由库的开发者去实现更好,尤其是在游戏开发中,逻辑全部是单线程的,回调每次都走一遍同步上下文就显得多余了,所以ET框架提供了不使用同步上下文的实现ETTask,代码更加简洁更加高效,这个后面会讲到。

ET开源地址地址:egametang/ET: Unity3D Client And C# Server Framework (github.com)   qq群:474643097文章来源地址https://www.toymoban.com/news/detail-449661.html

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

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

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

相关文章

  • Python、Rust中的协程

    协程在不同的堆栈上同时运行,但每次只有一个协程运行,而其调用者则等待: F启动G,但G并不会立即运行,F必须显式的恢复G,然后 G 开始运行。 在任何时候,G 都可能转身并让步返回到 F。这会暂停 G 并继续 F 的恢复操作。 F再次调用resume,这会暂停F并继续G的yield。它们不

    2024年02月09日
    浏览(33)
  • Golang中的协程(goroutine)

    目录 进程 线程 并发 并行 协程(goroutine)  使用sync.WaitGroup等待协程执行完毕 多协程和多线程         进程就是程序在操作系统中的一次执行过程,是系统进行资源分配和调度的基本单位,进程是一个动态概念,是程序在执行过程中分配和管理资源的基本单位,每一个进程

    2024年02月05日
    浏览(37)
  • go的协程和管道运用案例

    2024年01月19日
    浏览(37)
  • 【Unity每日一记】“调皮的协程”,协程和多线程的区别在哪里

    👨‍💻个人主页 :@元宇宙-秩沅 👨‍💻 hallo 欢迎 点赞👍 收藏⭐ 留言📝 加关注✅! 👨‍💻 本文由 秩沅 原创 👨‍💻 收录于专栏 : unity每日一记 ⭐【软件设计师高频考点暴击】 ⭐【Unityc#专题篇】之c#系统化大礼包】 ⭐【unity数据持久化】数据管理类_PlayerPrfs ⭐【u

    2024年02月05日
    浏览(45)
  • [Unity] 基于迭代器的协程底层原理详解

    Unity 是单线程设计的游戏引擎, 所有对于 Unity 的调用都应该在主线程执行. 倘若我们要实现另外再执行一个任务, 该怎么做呢? 答案就是协程. 协程本质上是基于 C# yield 迭代器的, 使用 yield 语法生成的返回迭代器的方法, 其内部的逻辑执行, 是 “懒” 的, 只有在调用 MoveNext 的时

    2024年01月16日
    浏览(41)
  • Golang的协程调度器原理及GMP设计思想

    (1) 单进程时代不需要调度器 我们知道,一切的软件都是跑在操作系统上,真正用来干活(计算)的是CPU。早期的操作系统每个程序就是一个进程,知道一个程序运行完,才能进行下一个进程,就是“单进程时代” 一切的程序只能串行发生。 早期的单进程操作系统,面临2个问题

    2024年02月16日
    浏览(44)
  • Go语言中,如何做到数据按类别分发给特定的协程处理

    在 Go 语言中,如果你想按类别将数据分配给特定的协程(goroutine)进行处理,可以使用几种策略。下面我将提供一些方法和示例,说明如何根据数据类别将任务分配给不同的协程来处理。 使用通道(Channel)分发数据 使用映射函数和协程池 使用单一分发器(Dispatcher) 方法

    2024年04月28日
    浏览(28)
  • ET介绍——单线程异步

    前面几个例子都是多线程实现的异步,但是异步显然不仅仅是多线程的。我们在之前的例子中使用了Sleep来实现时间的等待,每一个计时器都需要使用一个线程,会导致线程切换频繁,这个实现效率很低,平常是不会这样做的。一般游戏逻辑中会设计一个单线程的计时器,我

    2024年02月05日
    浏览(40)
  • ET介绍——数值组件设计

    类似魔兽世界,moba这种技能极其复杂,灵活性要求极高的技能系统,必须需要一套及其灵活的数值结构来搭配。数值结构设计好了,实现技能系统就会非常简单,否则就是一场灾难。比如魔兽世界,一个人物的数值属性非常之多,移动速度,力量,怒气,能量,集中值,魔法

    2024年02月05日
    浏览(34)
  • ET介绍——事件机制EventSystem

    ECS最重要的特性一是数据跟逻辑分离,二是数据驱动逻辑。什么是数据驱动逻辑呢?不太好理解,我们举个例子 一个moba游戏,英雄都有血条,血条会在人物头上显示,也会在左上方头像UI上显示。这时候服务端发来一个扣血消息。我们怎么处理这个消息?第一种方法,在消息

    2024年02月05日
    浏览(41)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包