Просмотр исходного кода

牛逼了,玩出了好多花活出来,任何一个协程都可以加上.Timeout来实现超时取消
例如await session.Call(request).Timeout(1000)
这样Call协程会在1000毫秒后超时取消

tanghai 1 год назад
Родитель
Сommit
b3c9c66067

+ 1 - 1
Unity/Packages/cn.etetet.core/Runtime/ETTask/ETCancellationToken.cs

@@ -6,7 +6,7 @@ namespace ET
 {
     public class ETCancellationToken
     {
-        private HashSet<Action> actions = new HashSet<Action>();
+        private HashSet<Action> actions = new();
 
         public void Add(Action callback)
         {

+ 20 - 0
Unity/Packages/cn.etetet.core/Runtime/ETTask/ETTask.cs

@@ -134,6 +134,16 @@ namespace ET
             this.SetCancelToken(cancellationToken);
             InnerCoroutine().Coroutine();
         }
+        
+        /// <summary>
+        /// 在await的同时可以换一个新的cancellationToken
+        /// </summary>
+        [DebuggerHidden]
+        public async ETTask NewCancel(ETCancellationToken cancellationToken)
+        {
+            this.SetCancelToken(cancellationToken);
+            await this;
+        }
 
         [DebuggerHidden]
         public ETTask GetAwaiter()
@@ -299,6 +309,16 @@ namespace ET
             this.SetCancelToken(cancellationToken);
             InnerCoroutine().Coroutine();
         }
+        
+        /// <summary>
+        /// 在await的同时可以换一个新的cancellationToken
+        /// </summary>
+        [DebuggerHidden]
+        public async ETTask<T> NewCancel(ETCancellationToken cancellationToken)
+        {
+            this.SetCancelToken(cancellationToken);
+            return await this;
+        }
 
         [DebuggerHidden]
         public ETTask<T> GetAwaiter()

+ 1 - 1
Unity/Packages/cn.etetet.core/Runtime/Fiber/Fiber.cs

@@ -18,7 +18,7 @@ namespace ET
         // 该字段只能框架使用,绝对不能改成public,改了后果自负
         [StaticField]
         [ThreadStatic]
-        internal static Fiber Instance;
+        public static Fiber Instance;
         
         public bool IsDisposed;
         

+ 0 - 22
Unity/Packages/cn.etetet.core/Scripts/Hotfix/Share/ETCancelationTokenHelper.cs

@@ -1,22 +0,0 @@
-namespace ET
-{
-    public static class ETCancelationTokenHelper
-    {
-        public static async ETTask CancelAfter(this ETCancellationToken self, Fiber fiber, long afterTimeCancel)
-        {
-            if (self.IsCancel())
-            {
-                return;
-            }
-
-            await fiber.Root.GetComponent<TimerComponent>().WaitAsync(afterTimeCancel);
-            
-            if (self.IsCancel())
-            {
-                return;
-            }
-            
-            self.Cancel();
-        }
-    }
-}

+ 87 - 0
Unity/Packages/cn.etetet.core/Scripts/Hotfix/Share/ETCancellationTokenHelper.cs

@@ -0,0 +1,87 @@
+using System;
+
+namespace ET
+{
+    public static class ETCancellationTokenHelper
+    {
+        private static async ETTask Timeout(this ETCancellationToken self, long afterTimeCancel)
+        {
+            if (afterTimeCancel <= 0)
+            {
+                return;
+            }
+            
+            if (self.IsCancel())
+            {
+                return;
+            }
+
+            // 这里用了Fiber.Instance是因为我知道有什么后果, 你们千万不能乱用这个Fiber.Instance
+            await Fiber.Instance.Root.GetComponent<TimerComponent>().WaitAsync(afterTimeCancel);
+            if (self.IsCancel())
+            {
+                return;
+            }
+            self.Cancel();
+        }
+        
+        /// <summary>
+        /// 增加一个canceltoken,可以用新增的canceltoken取消协程,当然也可以用老的取消
+        /// </summary>
+        public static async ETTask AddCancel(this ETTask task, ETCancellationToken addCancelToken)
+        {
+            if (addCancelToken == null)
+            {
+                throw new Exception("add cancel token is null");
+            }
+            ETCancellationToken cancelToken = await ETTaskHelper.GetCancelToken();
+            
+            cancelToken?.Add(addCancelToken.Cancel);
+            
+            await task.NewCancel(addCancelToken);
+        }
+        
+        /// <summary>
+        /// 增加一个canceltoken,可以用新增的canceltoken取消协程,当然也可以用老的取消
+        /// </summary>
+        public static async ETTask<T> AddCancel<T>(this ETTask<T> task, ETCancellationToken addCancelToken)
+        {
+            if (addCancelToken == null)
+            {
+                throw new Exception("add cancel token is null");
+            }
+            
+            ETCancellationToken cancelToken = await ETTaskHelper.GetCancelToken();
+            
+            cancelToken?.Add(addCancelToken.Cancel);
+            
+            return await task.NewCancel(addCancelToken);
+        }
+        
+        public static async ETTask Timeout(this ETTask task, ETCancellationToken cancellationToken, long afterTimeCancel)
+        {
+            cancellationToken.Timeout(afterTimeCancel).Coroutine();
+            await AddCancel(task, cancellationToken);
+        }
+        
+        public static async ETTask<T> Timeout<T>(this ETTask<T> task, ETCancellationToken cancellationToken, long afterTimeCancel)
+        {
+            cancellationToken.Timeout(afterTimeCancel).Coroutine();
+            return await AddCancel(task, cancellationToken);
+        }
+        
+        public static async ETTask Timeout(this ETTask task, long afterTimeCancel)
+        {
+            ETCancellationToken cancellationToken = new();
+            cancellationToken.Timeout(afterTimeCancel).Coroutine();
+            await AddCancel(task, cancellationToken);
+        }
+        
+        public static async ETTask<T> Timeout<T>(this ETTask<T> task, long afterTimeCancel)
+        {
+            ETCancellationToken cancellationToken = new();
+            cancellationToken.Timeout(afterTimeCancel).Coroutine();
+            return await AddCancel(task, cancellationToken);
+        }
+    }
+}

+ 1 - 1
Unity/Packages/cn.etetet.core/Scripts/Hotfix/Share/ETCancelationTokenHelper.cs.meta → Unity/Packages/cn.etetet.core/Scripts/Hotfix/Share/ETCancellationTokenHelper.cs.meta

@@ -1,5 +1,5 @@
 fileFormatVersion: 2
-guid: 94ef460aff219284a90c2001b88cb583
+guid: b857604ca729c9e44ae0cc89e4e4be0c
 MonoImporter:
   externalObjects: {}
   serializedVersion: 2

+ 5 - 31
Unity/Packages/cn.etetet.core/Scripts/Hotfix/Share/Message/SessionSystem.cs

@@ -42,12 +42,13 @@ namespace ET
             }
             action.SetResult(response);
         }
-        
+
         public static async ETTask<IResponse> Call(this Session self, IRequest request)
         {
             int rpcId = ++self.RpcId;
             RpcInfo rpcInfo = new(request.GetType());
             self.requestCallbacks[rpcId] = rpcInfo;
+            
             request.RpcId = rpcId;
 
             self.Send(request);
@@ -65,8 +66,8 @@ namespace ET
                 action.SetResult(response);
             }
 
-            IResponse ret;
             ETCancellationToken cancellationToken = await ETTaskHelper.GetCancelToken();
+            IResponse ret;
             try
             {
                 cancellationToken?.Add(CancelAction);
@@ -79,36 +80,9 @@ namespace ET
             return ret;
         }
 
-        public static async ETTask<IResponse> Call(this Session self, IRequest request, int time = 0)
+        public static async ETTask<IResponse> Call(this Session self, IRequest request, int timeout)
         {
-            int rpcId = ++self.RpcId;
-            RpcInfo rpcInfo = new(request.GetType());
-            self.requestCallbacks[rpcId] = rpcInfo;
-            request.RpcId = rpcId;
-            self.Send(request);
-
-            if (time > 0)
-            {
-                async ETTask Timeout()
-                {
-                    await self.Root().GetComponent<TimerComponent>().WaitAsync(time);
-                    if (!self.requestCallbacks.TryGetValue(rpcId, out RpcInfo action))
-                    {
-                        return;
-                    }
-
-                    if (!self.requestCallbacks.Remove(rpcId))
-                    {
-                        return;
-                    }
-                    
-                    action.SetException(new Exception($"session call timeout: {action.RequestType.FullName} {time}"));
-                }
-                
-                Timeout().Coroutine();
-            }
-
-            return await rpcInfo.Wait();
+            return await self.Call(request).Timeout(timeout);
         }
 
         public static void Send(this Session self, IMessage message)

+ 0 - 42
Unity/Packages/cn.etetet.core/Scripts/Hotfix/Share/ObjectWait/ObjectWaitSystem.cs

@@ -26,48 +26,7 @@ namespace ET
         public static async ETTask<T> Wait<T>(this ObjectWait self) where T : struct, IWaitType
         {
             ResultCallback<T> tcs = new ResultCallback<T>();
-            Type type = typeof (T);
-            self.tcss.Add(type, tcs);
-
-            void CancelAction()
-            {
-                self.Notify(new T() { Error = WaitTypeError.Cancel });
-            }
-
-            T ret;
             ETCancellationToken cancellationToken = await ETTaskHelper.GetCancelToken();
-            try
-            {
-                cancellationToken?.Add(CancelAction);
-                ret = await tcs.Task;
-            }
-            finally
-            {
-                cancellationToken?.Remove(CancelAction);    
-            }
-            return ret;
-        }
-
-        public static async ETTask<T> Wait<T>(this ObjectWait self, int timeout) where T : struct, IWaitType
-        {
-            ResultCallback<T> tcs = new ResultCallback<T>();
-            async ETTask WaitTimeout()
-            {
-                await self.Root().GetComponent<TimerComponent>().WaitAsync(timeout);
-                ETCancellationToken cancellationToken = await ETTaskHelper.GetCancelToken();
-                if (cancellationToken.IsCancel())
-                {
-                    return;
-                }
-                if (tcs.IsDisposed)
-                {
-                    return;
-                }
-                self.Notify(new T() { Error = WaitTypeError.Timeout });
-            }
-            
-            WaitTimeout().Coroutine();
-            
             self.tcss.Add(typeof (T), tcs);
             
             void CancelAction()
@@ -76,7 +35,6 @@ namespace ET
             }
             
             T ret;
-            ETCancellationToken cancellationToken = await ETTaskHelper.GetCancelToken();
             try
             {
                 cancellationToken?.Add(CancelAction);

+ 24 - 0
Unity/Packages/cn.etetet.statesync/Scripts/HotfixView/Client/Opera/OperaComponentSystem.cs

@@ -35,6 +35,11 @@ namespace ET.Client
             {
                 self.Test2().Coroutine();
             }
+            
+            if (Input.GetKeyDown(KeyCode.A))
+            {
+                self.TestCancelAfter().Coroutine();
+            }
 
             if (Input.GetKeyDown(KeyCode.T))
             {
@@ -63,5 +68,24 @@ namespace ET.Client
             }
             Log.Debug($"Croutine 2 end2");
         }
+        
+        private static async ETTask TestCancelAfter(this OperaComponent self)
+        {
+            ETCancellationToken oldCancellationToken = await ETTaskHelper.GetCancelToken();
+            
+            Log.Debug($"TestCancelAfter start");
+            ETCancellationToken newCancellationToken = new();
+            await self.Fiber().Root.GetComponent<TimerComponent>().WaitAsync(3000).Timeout(newCancellationToken, 1000);
+            if (newCancellationToken.IsCancel())
+            {
+                Log.Debug($"TestCancelAfter newCancellationToken is cancel!");
+            }
+            
+            if (!oldCancellationToken.IsCancel())
+            {
+                Log.Debug($"TestCancelAfter oldCancellationToken is not cancel!");
+            }
+            Log.Debug($"TestCancelAfter end");
+        }
     }
 }