ET介绍——单线程异步

Posted Flamesky

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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

求一个java 单线程 实现异步处理的例子

例如NIO NIO是异步处理

参考技术A ApplicationEvent 参考技术B 单线程怎么 异步 .我的天啊... Class A exetends Thread
run()
new B(this).start();

public doA()
system.out.println("A");


Class B exetends Thread
A a;
public b (A a)
this.a=a;

int i=0;
run()
while()
i++;
if(i==10)
doB();



public void doB()
this.doA();


参考技术C 不知道

以上是关于ET介绍——单线程异步的主要内容,如果未能解决你的问题,请参考以下文章

python对比线程,进程,携程,异步,哪个快

js异步——事件循环和消息队列

nodejs真的是单线程吗?

求一个java 单线程 实现异步处理的例子

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

js的单线程和异步