gpt4 book ai didi

ET介绍——CSharp协程

转载 作者:我是一只小鸟 更新时间:2023-05-19 06:31:19 32 4
gpt4 key购买 nike

什么是协程

说到协程,我们先了解什么是异步,异步简单说来就是,我要发起一个调用,但是这个被调用方(可能是其它线程,也可能是IO)出结果需要一段时间,我不想让这个调用阻塞住调用方的整个线程,因此传给被调用方一个回调函数,被调用方运行完成后回调这个回调函数就能通知调用方继续往下执行。举个例子: 下面的代码,主线程一直循环,每循环一次sleep 1毫秒,计数加一,每10000次打印一次.

                          
                            private
                          
                          
                            static
                          
                          
                            void
                          
                          
                             Main()
        {
            
                          
                          
                            int
                          
                           loopCount = 
                          
                            0
                          
                          
                            ;
            
                          
                          
                            while
                          
                           (
                          
                            true
                          
                          
                            )
            {
                
                          
                          
                            int
                          
                           temp =
                          
                             watcherValue;
                
                Thread.Sleep(
                          
                          
                            1
                          
                          
                            );
                
                
                          
                          ++
                          
                            loopCount;
                
                          
                          
                            if
                          
                           (loopCount % 
                          
                            10000
                          
                           == 
                          
                            0
                          
                          
                            )
                {
                    Console.WriteLine($
                          
                          
                            "
                          
                          
                            loop count: {loopCount}
                          
                          
                            "
                          
                          
                            );
                }
            }
        }
                          
                        

  。

这时我需要加个功能,在程序一开始,我希望在5秒钟之后打印出loopCount的值。看到5秒后我们可以想到Sleep方法,它会阻塞线程一定时间然后继续执行。我们显然不能在主线程中Sleep,因为会破坏掉每10000次计数打印一次的逻辑.

                          
                            //
                          
                          
                             example2_1
                          
                          
                            class
                          
                          
                             Program
    {
        
                          
                          
                            private
                          
                          
                            static
                          
                          
                            int
                          
                           loopCount = 
                          
                            0
                          
                          
                            ;

        
                          
                          
                            private
                          
                          
                            static
                          
                          
                            void
                          
                          
                             Main()
        {
            OneThreadSynchronizationContext _ 
                          
                          =
                          
                             OneThreadSynchronizationContext.Instance;
            
            WaitTimeAsync(
                          
                          
                            5000
                          
                          
                            , WaitTimeFinishCallback);
            
            
                          
                          
                            while
                          
                           (
                          
                            true
                          
                          
                            )
            {
                OneThreadSynchronizationContext.Instance.Update();
                
                Thread.Sleep(
                          
                          
                            1
                          
                          
                            );
                
                
                          
                          ++
                          
                            loopCount;
                
                          
                          
                            if
                          
                           (loopCount % 
                          
                            10000
                          
                           == 
                          
                            0
                          
                          
                            )
                {
                    Console.WriteLine($
                          
                          
                            "
                          
                          
                            loop count: {loopCount}
                          
                          
                            "
                          
                          
                            );
                }
            }
        }

        
                          
                          
                            private
                          
                          
                            static
                          
                          
                            void
                          
                           WaitTimeAsync(
                          
                            int
                          
                          
                             waitTime, Action action)
        {
            Thread thread 
                          
                          = 
                          
                            new
                          
                           Thread(()=>
                          
                            WaitTime(waitTime, action));
            thread.Start();
        }
        
        
                          
                          
                            private
                          
                          
                            static
                          
                          
                            void
                          
                          
                             WaitTimeFinishCallback()
        {
            Console.WriteLine($
                          
                          
                            "
                          
                          
                            WaitTimeAsync finsih loopCount的值是: {loopCount}
                          
                          
                            "
                          
                          
                            );
        }

        
                          
                          
                            ///
                          
                          
                            <summary>
                          
                          
                            ///
                          
                          
                             在另外的线程等待
        
                          
                          
                            ///
                          
                          
                            </summary>
                          
                          
                            private
                          
                          
                            static
                          
                          
                            void
                          
                           WaitTime(
                          
                            int
                          
                          
                             waitTime, Action action)
        {
            Thread.Sleep(waitTime);
            
            
                          
                          
                            //
                          
                          
                             将action扔回主线程执行
                          
                          
            OneThreadSynchronizationContext.Instance.Post((o)=>action(), 
                          
                            null
                          
                          
                            );
        }
    }
                          
                        

  。

我们在这里设计了一个WaitTimeAsync方法,WaitTimeAsync其实就是一个典型的异步方法,它从主线程发起调用,传入了一个WaitTimeFinishCallback回调方法做参数,开启了一个线程,线程Sleep一定时间后,将传过来的回调扔回到主线程执行。OneThreadSynchronizationContext是一个跨线程队列,任何线程可以往里面扔委托,OneThreadSynchronizationContext的Update方法在主线程中调用,会将这些委托取出来放到主线程执行。为什么回调方法需要扔回到主线程执行呢?因为回调方法中读取了loopCount,loopCount在主线程中也有读写,所以要么加锁,要么永远保证只在主线程中读写。加锁是个不好的做法,代码中到处是锁会导致阅读跟维护困难,很容易产生多线程bug。这种将逻辑打包成委托然后扔回另外一个线程是多线程开发中常用的技巧.

我们可能又有个新需求,WaitTimeFinishCallback执行完成之后,再想等3秒,再打印一下loopCount.

                          
                            private
                          
                          
                            static
                          
                          
                            void
                          
                           WaitTimeAsync(
                          
                            int
                          
                          
                             waitTime, Action action)
        {
            Thread thread 
                          
                          = 
                          
                            new
                          
                           Thread(()=>
                          
                            WaitTime(waitTime, action));
            thread.Start();
        }
        
                          
                          
                            private
                          
                          
                            static
                          
                          
                            void
                          
                          
                             WaitTimeFinishCallback()
        {
            Console.WriteLine($
                          
                          
                            "
                          
                          
                            WaitTimeAsync finsih loopCount的值是: {loopCount}
                          
                          
                            "
                          
                          
                            );
            WaitTimeAsync(
                          
                          
                            3000
                          
                          
                            , WaitTimeFinishCallback2);
        }
        
        
                          
                          
                            private
                          
                          
                            static
                          
                          
                            void
                          
                          
                             WaitTimeFinishCallback2()
        {
            Console.WriteLine($
                          
                          
                            "
                          
                          
                            WaitTimeAsync finsih loopCount的值是: {loopCount}
                          
                          
                            "
                          
                          
                            );
        }
                          
                        

  。

我们这时还可能改需求,需要在程序启动5秒后,接下来4秒,再接下来3秒,打印loopCount,也就是上面的逻辑中间再插入一个3秒等待.

                          
                            private
                          
                          
                            static
                          
                          
                            void
                          
                           WaitTimeAsync(
                          
                            int
                          
                          
                             waitTime, Action action)
        {
            Thread thread 
                          
                          = 
                          
                            new
                          
                           Thread(()=>
                          
                            WaitTime(waitTime, action));
            thread.Start();
        }
        
        
                          
                          
                            private
                          
                          
                            static
                          
                          
                            void
                          
                          
                             WaitTimeFinishCallback()
        {
            Console.WriteLine($
                          
                          
                            "
                          
                          
                            WaitTimeAsync finsih loopCount的值是: {loopCount}
                          
                          
                            "
                          
                          
                            );
            WaitTimeAsync(
                          
                          
                            4000
                          
                          
                            , WaitTimeFinishCallback3);
        }
        
        
                          
                          
                            private
                          
                          
                            static
                          
                          
                            void
                          
                          
                             WaitTimeFinishCallback3()
        {
            Console.WriteLine($
                          
                          
                            "
                          
                          
                            WaitTimeAsync finsih loopCount的值是: {loopCount}
                          
                          
                            "
                          
                          
                            );
            WaitTimeAsync(
                          
                          
                            3000
                          
                          
                            , WaitTimeFinishCallback2);
        }
        
        
                          
                          
                            private
                          
                          
                            static
                          
                          
                            void
                          
                          
                             WaitTimeFinishCallback2()
        {
            Console.WriteLine($
                          
                          
                            "
                          
                          
                            WaitTimeAsync finsih loopCount的值是: {loopCount}
                          
                          
                            "
                          
                          
                            );
        }
                          
                        

  。

这样中间插入一段代码,显得非常麻烦。这里可以回答什么是协程了,其实这一串串回调就是协程.

ET开源地址地址: egametang/ET: Unity3D Client And C# Server Framework (github.com)    qq群:474643097 。

最后此篇关于ET介绍——CSharp协程的文章就讲到这里了,如果你想了解更多关于ET介绍——CSharp协程的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com