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

Unity的CancellationTokenSource在超时Cancel的方法没有投递到同步上下文,因此会回调到其它线程,而服务端不会,所以这是一个bug。增加ETCancellationTokenSource, 来替代CancellationTokenSource

tanghai 6 лет назад
Родитель
Сommit
584eecae4d

+ 3 - 0
Server/Model/Server.Model.csproj

@@ -26,6 +26,9 @@
     <Compile Include="..\..\Unity\Assets\Model\Base\Async\AsyncETVoidMethodBuilder.cs">
       <Link>Base\Async\AsyncETVoidMethodBuilder.cs</Link>
     </Compile>
+    <Compile Include="..\..\Unity\Assets\Model\Base\Async\ETCancellationTokenSource.cs">
+      <Link>Base\Async\ETCancellationTokenSource.cs</Link>
+    </Compile>
     <Compile Include="..\..\Unity\Assets\Model\Base\Async\ETTask.cs">
       <Link>Base\Async\ETTask.cs</Link>
     </Compile>

+ 78 - 0
Unity/Assets/Model/Base/Async/ETCancellationTokenSource.cs

@@ -0,0 +1,78 @@
+using System.Threading;
+
+namespace ETModel
+{
+    [ObjectSystem]
+    public class ETCancellationTokenSourceAwakeSystem: AwakeSystem<ETCancellationTokenSource>
+    {
+        public override void Awake(ETCancellationTokenSource self)
+        {
+            self.CancellationTokenSource = new CancellationTokenSource();
+        }
+    }
+    
+    [ObjectSystem]
+    public class ETCancellationTokenSourceAwake2System: AwakeSystem<ETCancellationTokenSource, long>
+    {
+        public override void Awake(ETCancellationTokenSource self, long afterTimeCancel)
+        {
+            self.CancellationTokenSource = new CancellationTokenSource();
+            self.CancelAfter(afterTimeCancel).Coroutine();
+        }
+    }
+    
+    public class ETCancellationTokenSource: Component
+    {
+        public CancellationTokenSource CancellationTokenSource;
+
+        public void Cancel()
+        {
+            if (this.CancellationTokenSource == null)
+            {
+                return;
+            }
+            CancellationTokenSource cts = this.CancellationTokenSource;
+            this.CancellationTokenSource = null;
+            cts?.Cancel();
+        }
+
+        public async ETVoid CancelAfter(long afterTimeCancel)
+        {
+            if (this.CancellationTokenSource == null)
+            {
+                return;
+            }
+            
+            await Game.Scene.GetComponent<TimerComponent>().WaitAsync(afterTimeCancel);
+            
+            if (this.CancellationTokenSource == null)
+            {
+                return;
+            }
+            
+            CancellationTokenSource cts = this.CancellationTokenSource;
+            this.CancellationTokenSource = null;
+            cts?.Cancel();
+        }
+
+        public CancellationToken Token
+        {
+            get
+            {
+                return this.CancellationTokenSource.Token;
+            }
+        }
+
+        public override void Dispose()
+        {
+            if (this.IsDisposed)
+            {
+                return;
+            }
+            
+            base.Dispose();
+            
+            this.CancellationTokenSource?.Cancel();
+        }
+    }
+}

+ 1 - 0
Unity/Unity.Model.csproj

@@ -57,6 +57,7 @@
     <Compile Include="Assets\Model\Base\Async\AsyncETTaskMethodBuilder.cs" />
     <Compile Include="Assets\Model\Base\Async\AsyncETVoidMethodBuilder.cs" />
     <Compile Include="Assets\Model\Base\Async\AsyncMethodBuilderAttribute.cs" />
+    <Compile Include="Assets\Model\Base\Async\ETCancellationTokenSource.cs" />
     <Compile Include="Assets\Model\Base\Async\ETTask.cs" />
     <Compile Include="Assets\Model\Base\Async\ETTaskCompletionSource.cs" />
     <Compile Include="Assets\Model\Base\Async\ETTaskFactory.cs" />