|
单线程异步
前面几个例子都是多线程实现的异步,但是异步显然不仅仅是多线程的。我们在之前的例子中使用了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.cnblogs.com/flamesky/archive/2023/05/18/17413679.html
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作! |
|