Jelajahi Sumber

增加自定义Task ETTask,ETTask不会使用同步上下文,必须保证调用跟回调都在主线程。Unity跟ETServer都是单线程逻辑,所以这一修改将大大提高性能
建议写逻辑时尽量使用ETTask替代Task

tanghai 7 tahun lalu
induk
melakukan
27d21587f7
75 mengubah file dengan 2019 tambahan dan 163 penghapusan
  1. 1 0
      Server/App/Server.App.csproj
  2. 2 2
      Server/Hotfix/Handler/Actor_TestRequestHandler.cs
  3. 2 2
      Server/Hotfix/Module/Actor/GateSessionActorInterceptInterceptTypeHandler.cs
  4. 5 5
      Server/Hotfix/Module/Actor/MailBoxComponentSystem.cs
  5. 5 5
      Server/Hotfix/Module/ActorLocation/ActorLocationSenderSystem.cs
  6. 5 5
      Server/Hotfix/Module/ActorLocation/LocationProxyComponentSystem.cs
  7. 1 1
      Server/Hotfix/Module/Benchmark/BenchmarkComponentSystem.cs
  8. 5 5
      Server/Hotfix/Module/BigWorld/LockComponentSystem.cs
  9. 3 3
      Server/Hotfix/Module/BigWorld/MasterComponentSystem.cs
  10. 7 7
      Server/Hotfix/Module/DB/DBProxyComponentSystem.cs
  11. 2 2
      Server/Hotfix/Module/Demo/C2M_TestActorRequestHandler.cs
  12. 1 0
      Server/Hotfix/Server.Hotfix.csproj
  13. 2 2
      Server/Model/Module/Actor/AMActorHandler.cs
  14. 1 1
      Server/Model/Module/Actor/AMActorRpcHandler.cs
  15. 3 5
      Server/Model/Module/Actor/ActorTask.cs
  16. 1 3
      Server/Model/Module/Actor/IActorInterceptTypeHandler.cs
  17. 1 1
      Server/Model/Module/Actor/IMActorHandler.cs
  18. 1 1
      Server/Model/Module/Actor/MailBoxComponent.cs
  19. 2 2
      Server/Model/Module/ActorLocation/AMActorLocationHandler.cs
  20. 2 2
      Server/Model/Module/ActorLocation/AMActorLocationRpcHandler.cs
  21. 1 1
      Server/Model/Module/ActorLocation/ActorLocationSender.cs
  22. 5 5
      Server/Model/Module/ActorLocation/LocationComponent.cs
  23. 1 1
      Server/Model/Module/BigWorld/LockComponent.cs
  24. 2 2
      Server/Model/Module/BigWorld/MasterComponent.cs
  25. 17 17
      Server/Model/Module/DB/DBCacheComponent.cs
  26. 4 4
      Server/Model/Module/DB/DBQueryBatchTask.cs
  27. 4 4
      Server/Model/Module/DB/DBQueryJsonTask.cs
  28. 4 4
      Server/Model/Module/DB/DBQueryTask.cs
  29. 4 4
      Server/Model/Module/DB/DBSaveBatchTask.cs
  30. 4 4
      Server/Model/Module/DB/DBSaveTask.cs
  31. 2 4
      Server/Model/Module/DB/DBTask.cs
  32. 4 4
      Server/Model/Module/DB/DBTaskQueue.cs
  33. 1 1
      Server/Model/Module/Http/HttpComponent.cs
  34. 34 0
      Server/Model/Server.Model.csproj
  35. 1 0
      Server/ThirdParty/Google.Protobuf/Google.Protobuf.csproj
  36. 1 0
      Server/ThirdParty/KcpLib/KcpLib.csproj
  37. 1 0
      Server/ThirdParty/MongodbDriver/DotNetCoreDriver/MongoDB.Bson/MongoDB.Bson.csproj
  38. 1 0
      Server/ThirdParty/MongodbDriver/DotNetCoreDriver/MongoDB.Driver.Core/MongoDB.Driver.Core.csproj
  39. 1 0
      Server/ThirdParty/MongodbDriver/DotNetCoreDriver/MongoDB.Driver/MongoDB.Driver.csproj
  40. 4 4
      Unity/Assets/Hotfix/Module/Message/Session.cs
  41. 8 0
      Unity/Assets/Model/Base/Async.meta
  42. 12 0
      Unity/Assets/Model/Base/Async/AsyncMethodBuilderAttribute.cs
  43. 11 0
      Unity/Assets/Model/Base/Async/AsyncMethodBuilderAttribute.cs.meta
  44. 24 0
      Unity/Assets/Model/Base/Async/AsyncUnit.cs
  45. 11 0
      Unity/Assets/Model/Base/Async/AsyncUnit.cs.meta
  46. 72 0
      Unity/Assets/Model/Base/Async/CancellationTokenExtensions.cs
  47. 11 0
      Unity/Assets/Model/Base/Async/CancellationTokenExtensions.cs.meta
  48. 267 0
      Unity/Assets/Model/Base/Async/ETAsyncTaskMethodBuilder.cs
  49. 11 0
      Unity/Assets/Model/Base/Async/ETAsyncTaskMethodBuilder.cs.meta
  50. 83 0
      Unity/Assets/Model/Base/Async/ETAsyncTaskVoidMethodBuilder.cs
  51. 11 0
      Unity/Assets/Model/Base/Async/ETAsyncTaskVoidMethodBuilder.cs.meta
  52. 458 0
      Unity/Assets/Model/Base/Async/ETTask.cs
  53. 11 0
      Unity/Assets/Model/Base/Async/ETTask.cs.meta
  54. 421 0
      Unity/Assets/Model/Base/Async/ETTaskCompletionSource.cs
  55. 11 0
      Unity/Assets/Model/Base/Async/ETTaskCompletionSource.cs.meta
  56. 87 0
      Unity/Assets/Model/Base/Async/ETTaskFactory.cs
  57. 11 0
      Unity/Assets/Model/Base/Async/ETTaskFactory.cs.meta
  58. 42 0
      Unity/Assets/Model/Base/Async/ETTaskVoid.cs
  59. 11 0
      Unity/Assets/Model/Base/Async/ETTaskVoid.cs.meta
  60. 62 0
      Unity/Assets/Model/Base/Async/IAwaiter.cs
  61. 11 0
      Unity/Assets/Model/Base/Async/IAwaiter.cs.meta
  62. 125 0
      Unity/Assets/Model/Base/Async/LazyPromise.cs
  63. 11 0
      Unity/Assets/Model/Base/Async/LazyPromise.cs.meta
  64. 16 0
      Unity/Assets/Model/Base/Async/MoveNextRunner.cs
  65. 11 0
      Unity/Assets/Model/Base/Async/MoveNextRunner.cs.meta
  66. 3 3
      Unity/Assets/Model/Component/SceneChangeComponent.cs
  67. 10 15
      Unity/Assets/Model/Component/TimerComponent.cs
  68. 3 3
      Unity/Assets/Model/Entity/UnityWebRequestAsync.cs
  69. 9 9
      Unity/Assets/Model/Entity/WWWAsync.cs
  70. 4 0
      Unity/Assets/Model/Init.cs
  71. 4 4
      Unity/Assets/Model/Module/AssetsBundle/AssetsBundleLoaderAsync.cs
  72. 4 4
      Unity/Assets/Model/Module/AssetsBundle/AssetsLoaderAsync.cs
  73. 5 5
      Unity/Assets/Model/Module/Demo/MoveComponent.cs
  74. 6 6
      Unity/Assets/Model/Module/Message/Session.cs
  75. 14 1
      Unity/Unity.Model.csproj

+ 1 - 0
Server/App/Server.App.csproj

@@ -5,6 +5,7 @@
     <TargetFramework>netcoreapp2.1</TargetFramework>
     <AssemblyName>App</AssemblyName>
     <RootNamespace>App</RootNamespace>
+    <LangVersion>7.3</LangVersion>
   </PropertyGroup>
 
   <PropertyGroup>

+ 2 - 2
Server/Hotfix/Handler/Actor_TestRequestHandler.cs

@@ -7,9 +7,9 @@ namespace ETHotfix
 	[ActorMessageHandler(AppType.Map)]
 	public class Actor_TestRequestHandler : AMActorLocationRpcHandler<Unit, Actor_TestRequest, Actor_TestResponse>
 	{
-		protected override async Task Run(Unit unit, Actor_TestRequest message, Action<Actor_TestResponse> reply)
+		protected override async ETTask Run(Unit unit, Actor_TestRequest message, Action<Actor_TestResponse> reply)
 		{
-			await Task.CompletedTask;
+			await ETTask.CompletedTask;
 			reply(new Actor_TestResponse() {Response = "response actor rpc"});
 		}
 	}

+ 2 - 2
Server/Hotfix/Module/Actor/GateSessionActorInterceptInterceptTypeHandler.cs

@@ -10,7 +10,7 @@ namespace ETHotfix
 	[ActorInterceptTypeHandler(AppType.Gate, ActorInterceptType.GateSession)]
 	public class GateSessionActorInterceptInterceptTypeHandler : IActorInterceptTypeHandler
 	{
-		public async Task Handle(Session session, Entity entity, object actorMessage)
+		public async ETTask Handle(Session session, Entity entity, object actorMessage)
 		{
 			try
 			{
@@ -19,7 +19,7 @@ namespace ETHotfix
 				Session clientSession = entity as Session;
 				iActorMessage.ActorId = 0;
 				clientSession.Send(iActorMessage);
-				await Task.CompletedTask;
+				await ETTask.CompletedTask;
 			}
 			catch (Exception e)
 			{

+ 5 - 5
Server/Hotfix/Module/Actor/MailBoxComponentSystem.cs

@@ -39,12 +39,12 @@ namespace ETHotfix
 	/// </summary>
 	public static class MailBoxComponentHelper
 	{
-		public static async Task AddLocation(this MailBoxComponent self)
+		public static async ETTask AddLocation(this MailBoxComponent self)
 		{
 			await Game.Scene.GetComponent<LocationProxyComponent>().Add(self.Entity.Id, self.Entity.InstanceId);
 		}
 
-		public static async Task RemoveLocation(this MailBoxComponent self)
+		public static async ETTask RemoveLocation(this MailBoxComponent self)
 		{
 			await Game.Scene.GetComponent<LocationProxyComponent>().Remove(self.Entity.Id);
 		}
@@ -63,14 +63,14 @@ namespace ETHotfix
 			t.SetResult(self.Queue.Dequeue());
 		}
 
-		private static Task<ActorMessageInfo> GetAsync(this MailBoxComponent self)
+		private static ETTask<ActorMessageInfo> GetAsync(this MailBoxComponent self)
 		{
 			if (self.Queue.Count > 0)
 			{
-				return Task.FromResult(self.Queue.Dequeue());
+				return ETTask.FromResult(self.Queue.Dequeue());
 			}
 
-			self.Tcs = new TaskCompletionSource<ActorMessageInfo>();
+			self.Tcs = new ETTaskCompletionSource<ActorMessageInfo>();
 			return self.Tcs.Task;
 		}
 

+ 5 - 5
Server/Hotfix/Module/ActorLocation/ActorLocationSenderSystem.cs

@@ -91,15 +91,15 @@ namespace ETHotfix
 			t.SetResult(task);
 		}
 
-		private static Task<ActorTask> GetAsync(this ActorLocationSender self)
+		private static ETTask<ActorTask> GetAsync(this ActorLocationSender self)
 		{
 			if (self.WaitingTasks.Count > 0)
 			{
 				ActorTask task = self.WaitingTasks.Peek();
-				return Task.FromResult(task);
+				return ETTask.FromResult(task);
 			}
 
-			self.Tcs = new TaskCompletionSource<ActorTask>();
+			self.Tcs = new ETTaskCompletionSource<ActorTask>();
 			return self.Tcs.Task;
 		}
 
@@ -200,13 +200,13 @@ namespace ETHotfix
 		    self.Add(task);
 	    }
 
-		public static Task<IActorLocationResponse> Call(this ActorLocationSender self, IActorLocationRequest request)
+		public static ETTask<IActorLocationResponse> Call(this ActorLocationSender self, IActorLocationRequest request)
 		{
 			if (request == null)
 			{
 				throw new Exception($"actor location call message is null");
 			}
-			TaskCompletionSource<IActorLocationResponse> tcs = new TaskCompletionSource<IActorLocationResponse>();
+			ETTaskCompletionSource<IActorLocationResponse> tcs = new ETTaskCompletionSource<IActorLocationResponse>();
 			ActorTask task = new ActorTask(request, tcs);
 			self.Add(task);
 			return task.Tcs.Task;

+ 5 - 5
Server/Hotfix/Module/ActorLocation/LocationProxyComponentSystem.cs

@@ -22,31 +22,31 @@ namespace ETHotfix
 			self.LocationAddress = startConfig.GetComponent<InnerConfig>().IPEndPoint;
 		}
 
-		public static async Task Add(this LocationProxyComponent self, long key, long instanceId)
+		public static async ETTask Add(this LocationProxyComponent self, long key, long instanceId)
 		{
 			Session session = Game.Scene.GetComponent<NetInnerComponent>().Get(self.LocationAddress);
 			await session.Call(new ObjectAddRequest() { Key = key, InstanceId = instanceId });
 		}
 
-		public static async Task Lock(this LocationProxyComponent self, long key, long instanceId, int time = 1000)
+		public static async ETTask Lock(this LocationProxyComponent self, long key, long instanceId, int time = 1000)
 		{
 			Session session = Game.Scene.GetComponent<NetInnerComponent>().Get(self.LocationAddress);
 			await session.Call(new ObjectLockRequest() { Key = key, InstanceId = instanceId, Time = time });
 		}
 
-		public static async Task UnLock(this LocationProxyComponent self, long key, long oldInstanceId, long instanceId)
+		public static async ETTask UnLock(this LocationProxyComponent self, long key, long oldInstanceId, long instanceId)
 		{
 			Session session = Game.Scene.GetComponent<NetInnerComponent>().Get(self.LocationAddress);
 			await session.Call(new ObjectUnLockRequest() { Key = key, OldInstanceId = oldInstanceId, InstanceId = instanceId});
 		}
 
-		public static async Task Remove(this LocationProxyComponent self, long key)
+		public static async ETTask Remove(this LocationProxyComponent self, long key)
 		{
 			Session session = Game.Scene.GetComponent<NetInnerComponent>().Get(self.LocationAddress);
 			await session.Call(new ObjectRemoveRequest() { Key = key });
 		}
 
-		public static async Task<long> Get(this LocationProxyComponent self, long key)
+		public static async ETTask<long> Get(this LocationProxyComponent self, long key)
 		{
 			Session session = Game.Scene.GetComponent<NetInnerComponent>().Get(self.LocationAddress);
 			ObjectGetResponse response = (ObjectGetResponse)await session.Call(new ObjectGetRequest() { Key = key });

+ 1 - 1
Server/Hotfix/Module/Benchmark/BenchmarkComponentSystem.cs

@@ -57,7 +57,7 @@ namespace ETHotfix
 			}
 		}
 
-		public static async Task Send(this BenchmarkComponent self, Session session, int j)
+		public static async ETTask Send(this BenchmarkComponent self, Session session, int j)
 		{
 			try
 			{

+ 5 - 5
Server/Hotfix/Module/BigWorld/LockComponentSystem.cs

@@ -25,7 +25,7 @@ namespace ETHotfix
 			self.address = addr;
 		}
 		
-		public static async Task Lock(this LockComponent self)
+		public static async ETTask Lock(this LockComponent self)
 		{
 			++self.lockCount;
 
@@ -54,14 +54,14 @@ namespace ETHotfix
 			}
 		}
 
-		private static Task<bool> WaitLock(this LockComponent self)
+		private static ETTask<bool> WaitLock(this LockComponent self)
 		{
 			if (self.status == LockStatus.Locked)
 			{
-				return Task.FromResult(true);
+				return ETTask.FromResult(true);
 			}
 
-			TaskCompletionSource<bool> tcs = new TaskCompletionSource<bool>();
+			ETTaskCompletionSource<bool> tcs = new ETTaskCompletionSource<bool>();
 			self.queue.Enqueue(tcs);
 			return tcs.Task;
 		}
@@ -77,7 +77,7 @@ namespace ETHotfix
 
 				self.status = LockStatus.Locked;
 
-				foreach (TaskCompletionSource<bool> taskCompletionSource in self.queue)
+				foreach (ETTaskCompletionSource<bool> taskCompletionSource in self.queue)
 				{
 					taskCompletionSource.SetResult(true);
 				}

+ 3 - 3
Server/Hotfix/Module/BigWorld/MasterComponentSystem.cs

@@ -17,15 +17,15 @@ namespace ETHotfix
 			self.ghostsAddress.Remove(address);
 		}
 
-		public static Task<bool> Lock(this MasterComponent self, IPEndPoint address)
+		public static ETTask<bool> Lock(this MasterComponent self, IPEndPoint address)
 		{
 			if (self.lockedAddress == null)
 			{
 				self.lockedAddress = address;
-				return Task.FromResult(true);
+				return ETTask.FromResult(true);
 			}
 
-			TaskCompletionSource<bool> tcs = new TaskCompletionSource<bool>();
+			ETTaskCompletionSource<bool> tcs = new ETTaskCompletionSource<bool>();
 			LockInfo lockInfo = new LockInfo(address, tcs);
 			self.queue.Enqueue(lockInfo);
 			return tcs.Task;

+ 7 - 7
Server/Hotfix/Module/DB/DBProxyComponentSystem.cs

@@ -31,19 +31,19 @@ namespace ETHotfix
 			self.dbAddress = dbStartConfig.GetComponent<InnerConfig>().IPEndPoint;
 		}
 
-		public static async Task Save(this DBProxyComponent self, ComponentWithId component, bool needCache = true)
+		public static async ETTask Save(this DBProxyComponent self, ComponentWithId component, bool needCache = true)
 		{
 			Session session = Game.Scene.GetComponent<NetInnerComponent>().Get(self.dbAddress);
 			await session.Call(new DBSaveRequest { Component = component, NeedCache = needCache});
 		}
 
-		public static async Task SaveBatch(this DBProxyComponent self, List<ComponentWithId> components, bool needCache = true)
+		public static async ETTask SaveBatch(this DBProxyComponent self, List<ComponentWithId> components, bool needCache = true)
 		{
 			Session session = Game.Scene.GetComponent<NetInnerComponent>().Get(self.dbAddress);
 			await session.Call(new DBSaveBatchRequest { Components = components, NeedCache = needCache});
 		}
 
-		public static async Task Save(this DBProxyComponent self, ComponentWithId component, bool needCache, CancellationToken cancellationToken)
+		public static async ETTask Save(this DBProxyComponent self, ComponentWithId component, bool needCache, CancellationToken cancellationToken)
 		{
 			Session session = Game.Scene.GetComponent<NetInnerComponent>().Get(self.dbAddress);
 			await session.Call(new DBSaveRequest { Component = component, NeedCache = needCache}, cancellationToken);
@@ -55,7 +55,7 @@ namespace ETHotfix
 			await session.Call(new DBSaveRequest { Component = component,  NeedCache = false, CollectionName = "Log" });
 		}
 
-		public static async Task<T> Query<T>(this DBProxyComponent self, long id, bool needCache = true) where T: ComponentWithId
+		public static async ETTask<T> Query<T>(this DBProxyComponent self, long id, bool needCache = true) where T: ComponentWithId
 		{
 			Session session = Game.Scene.GetComponent<NetInnerComponent>().Get(self.dbAddress);
 			DBQueryResponse dbQueryResponse = (DBQueryResponse)await session.Call(new DBQueryRequest { CollectionName = typeof(T).Name, Id = id, NeedCache = needCache });
@@ -69,7 +69,7 @@ namespace ETHotfix
 		/// <param name="exp"></param>
 		/// <typeparam name="T"></typeparam>
 		/// <returns></returns>
-		public static async Task<List<ComponentWithId>> Query<T>(this DBProxyComponent self, Expression<Func<T ,bool>> exp) where T: ComponentWithId
+		public static async ETTask<List<ComponentWithId>> Query<T>(this DBProxyComponent self, Expression<Func<T ,bool>> exp) where T: ComponentWithId
 		{
 			ExpressionFilterDefinition<T> filter = new ExpressionFilterDefinition<T>(exp);
 			IBsonSerializerRegistry serializerRegistry = BsonSerializer.SerializerRegistry;
@@ -78,7 +78,7 @@ namespace ETHotfix
 			return await self.Query<T>(json);
 		}
 
-		public static async Task<List<ComponentWithId>> Query<T>(this DBProxyComponent self, List<long> ids, bool needCache = true) where T : ComponentWithId
+		public static async ETTask<List<ComponentWithId>> Query<T>(this DBProxyComponent self, List<long> ids, bool needCache = true) where T : ComponentWithId
 		{
 			Session session = Game.Scene.GetComponent<NetInnerComponent>().Get(self.dbAddress);
 			DBQueryBatchResponse dbQueryBatchResponse = (DBQueryBatchResponse)await session.Call(new DBQueryBatchRequest { CollectionName = typeof(T).Name, IdList = ids, NeedCache = needCache});
@@ -92,7 +92,7 @@ namespace ETHotfix
 		/// <param name="json"></param>
 		/// <typeparam name="T"></typeparam>
 		/// <returns></returns>
-		public static async Task<List<ComponentWithId>> Query<T>(this DBProxyComponent self, string json) where T : ComponentWithId
+		public static async ETTask<List<ComponentWithId>> Query<T>(this DBProxyComponent self, string json) where T : ComponentWithId
 		{
 			Session session = Game.Scene.GetComponent<NetInnerComponent>().Get(self.dbAddress);
 			DBQueryJsonResponse dbQueryJsonResponse = (DBQueryJsonResponse)await session.Call(new DBQueryJsonRequest { CollectionName = typeof(T).Name, Json = json });

+ 2 - 2
Server/Hotfix/Module/Demo/C2M_TestActorRequestHandler.cs

@@ -7,10 +7,10 @@ namespace ETHotfix
 	[ActorMessageHandler(AppType.Map)]
 	public class C2M_TestActorRequestHandler : AMActorLocationRpcHandler<Unit, C2M_TestActorRequest, M2C_TestActorResponse>
 	{
-		protected override async Task Run(Unit unit, C2M_TestActorRequest message, Action<M2C_TestActorResponse> reply)
+		protected override async ETTask Run(Unit unit, C2M_TestActorRequest message, Action<M2C_TestActorResponse> reply)
 		{
 			reply(new M2C_TestActorResponse(){Info = "actor rpc response"});
-			await Task.CompletedTask;
+			await ETTask.CompletedTask;
 		}
 	}
 }

+ 1 - 0
Server/Hotfix/Server.Hotfix.csproj

@@ -3,6 +3,7 @@
     <TargetFramework>netcoreapp2.1</TargetFramework>
     <AssemblyName>Hotfix</AssemblyName>
     <RootNamespace>ETHotfix</RootNamespace>
+    <LangVersion>7.3</LangVersion>
   </PropertyGroup>
   <PropertyGroup>
     <AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>

+ 2 - 2
Server/Model/Module/Actor/AMActorHandler.cs

@@ -7,7 +7,7 @@ namespace ETModel
 	{
 		protected abstract void Run(E entity, Message message);
 
-		public async Task Handle(Session session, Entity entity, object actorMessage)
+		public async ETTask Handle(Session session, Entity entity, object actorMessage)
 		{
 			Message msg = actorMessage as Message;
 			if (msg == null)
@@ -24,7 +24,7 @@ namespace ETModel
 
 			this.Run(e, msg);
 
-			await Task.CompletedTask;
+			await ETTask.CompletedTask;
 		}
 
 		public Type GetMessageType()

+ 1 - 1
Server/Model/Module/Actor/AMActorRpcHandler.cs

@@ -15,7 +15,7 @@ namespace ETModel
 
 		protected abstract Task Run(E unit, Request message, Action<Response> reply);
 
-		public async Task Handle(Session session, Entity entity, object actorMessage)
+		public async ETTask Handle(Session session, Entity entity, object actorMessage)
 		{
 			try
 			{

+ 3 - 5
Server/Model/Module/Actor/ActorTask.cs

@@ -1,12 +1,10 @@
-using System.Threading.Tasks;
-
-namespace ETModel
+namespace ETModel
 {
 	public struct ActorTask
 	{
 		public IActorRequest ActorRequest;
 		
-		public TaskCompletionSource<IActorLocationResponse> Tcs;
+		public ETTaskCompletionSource<IActorLocationResponse> Tcs;
 
 		public ActorTask(IActorLocationMessage actorRequest)
 		{
@@ -14,7 +12,7 @@ namespace ETModel
 			this.Tcs = null;
 		}
 		
-		public ActorTask(IActorLocationRequest actorRequest, TaskCompletionSource<IActorLocationResponse> tcs)
+		public ActorTask(IActorLocationRequest actorRequest, ETTaskCompletionSource<IActorLocationResponse> tcs)
 		{
 			this.ActorRequest = actorRequest;
 			this.Tcs = tcs;

+ 1 - 3
Server/Model/Module/Actor/IActorInterceptTypeHandler.cs

@@ -1,9 +1,7 @@
-using System.Threading.Tasks;
-
 namespace ETModel
 {
 	public interface IActorInterceptTypeHandler
 	{
-		Task Handle(Session session, Entity entity, object actorMessage);
+		ETTask Handle(Session session, Entity entity, object actorMessage);
 	}
 }

+ 1 - 1
Server/Model/Module/Actor/IMActorHandler.cs

@@ -5,7 +5,7 @@ namespace ETModel
 {
 	public interface IMActorHandler
 	{
-		Task Handle(Session session, Entity entity, object actorMessage);
+		ETTask Handle(Session session, Entity entity, object actorMessage);
 		Type GetMessageType();
 	}
 }

+ 1 - 1
Server/Model/Module/Actor/MailBoxComponent.cs

@@ -20,7 +20,7 @@ namespace ETModel
 		// 队列处理消息
 		public Queue<ActorMessageInfo> Queue = new Queue<ActorMessageInfo>();
 
-		public TaskCompletionSource<ActorMessageInfo> Tcs;
+		public ETTaskCompletionSource<ActorMessageInfo> Tcs;
 
 		public override void Dispose()
 		{

+ 2 - 2
Server/Model/Module/ActorLocation/AMActorLocationHandler.cs

@@ -7,7 +7,7 @@ namespace ETModel
 	{
 		protected abstract void Run(E entity, Message message);
 
-		public async Task Handle(Session session, Entity entity, object actorMessage)
+		public async ETTask Handle(Session session, Entity entity, object actorMessage)
 		{
 			Message msg = actorMessage as Message;
 			if (msg == null)
@@ -28,7 +28,7 @@ namespace ETModel
 			
 			this.Run(e, msg);
 			
-			await Task.CompletedTask;
+			await ETTask.CompletedTask;
 		}
 
 		public Type GetMessageType()

+ 2 - 2
Server/Model/Module/ActorLocation/AMActorLocationRpcHandler.cs

@@ -13,9 +13,9 @@ namespace ETModel
 			reply(response);
 		}
 
-		protected abstract Task Run(E unit, Request message, Action<Response> reply);
+		protected abstract ETTask Run(E unit, Request message, Action<Response> reply);
 
-		public async Task Handle(Session session, Entity entity, object actorMessage)
+		public async ETTask Handle(Session session, Entity entity, object actorMessage)
 		{
 			try
 			{

+ 1 - 1
Server/Model/Module/ActorLocation/ActorLocationSender.cs

@@ -22,7 +22,7 @@ namespace ETModel
 
 		public const int MaxFailTimes = 5;
 		
-		public TaskCompletionSource<ActorTask> Tcs;
+		public ETTaskCompletionSource<ActorTask> Tcs;
 
 		public override void Dispose()
 		{

+ 5 - 5
Server/Model/Module/ActorLocation/LocationComponent.cs

@@ -16,7 +16,7 @@ namespace ETModel
 		public override void Awake(LocationQueryTask self, long key)
 		{
 			self.Key = key;
-			self.Tcs = new TaskCompletionSource<long>();
+			self.Tcs = new ETTaskCompletionSource<long>();
 		}
 	}
 
@@ -24,9 +24,9 @@ namespace ETModel
 	{
 		public long Key;
 
-		public TaskCompletionSource<long> Tcs;
+		public ETTaskCompletionSource<long> Tcs;
 
-		public Task<long> Task
+		public ETTask<long> Task
 		{
 			get
 			{
@@ -163,13 +163,13 @@ namespace ETModel
 			}
 		}
 
-		public Task<long> GetAsync(long key)
+		public ETTask<long> GetAsync(long key)
 		{
 			if (!this.lockDict.ContainsKey(key))
 			{
 				this.locations.TryGetValue(key, out long instanceId);
 				Log.Info($"location get key: {key} {instanceId}");
-				return Task.FromResult(instanceId);
+				return ETTask.FromResult(instanceId);
 			}
 
 			LocationQueryTask task = ComponentFactory.CreateWithParent<LocationQueryTask, long>(this, key);

+ 1 - 1
Server/Model/Module/BigWorld/LockComponent.cs

@@ -20,6 +20,6 @@ namespace ETModel
 		public LockStatus status = LockStatus.LockedNot;
 		public IPEndPoint address;
 		public int lockCount;
-		public readonly Queue<TaskCompletionSource<bool>> queue = new Queue<TaskCompletionSource<bool>>();
+		public readonly Queue<ETTaskCompletionSource<bool>> queue = new Queue<ETTaskCompletionSource<bool>>();
 	}
 }

+ 2 - 2
Server/Model/Module/BigWorld/MasterComponent.cs

@@ -7,9 +7,9 @@ namespace ETModel
 	public class LockInfo
 	{
 		public IPEndPoint Address;
-		public TaskCompletionSource<bool> Tcs;
+		public ETTaskCompletionSource<bool> Tcs;
 
-		public LockInfo(IPEndPoint address, TaskCompletionSource<bool> tcs)
+		public LockInfo(IPEndPoint address, ETTaskCompletionSource<bool> tcs)
 		{
 			this.Address = address;
 			this.Tcs = tcs;

+ 17 - 17
Server/Model/Module/DB/DBCacheComponent.cs

@@ -33,24 +33,24 @@ namespace ETModel
 			}
 		}
 
-		public Task<bool> Add(ComponentWithId component, string collectionName = "")
+		public ETTask<bool> Add(ComponentWithId component, string collectionName = "")
 		{
-			TaskCompletionSource<bool> tcs = new TaskCompletionSource<bool>();
+			ETTaskCompletionSource<bool> tcs = new ETTaskCompletionSource<bool>();
 
 			if (string.IsNullOrEmpty(collectionName))
 			{
 				collectionName = component.GetType().Name;
 			}
-			DBSaveTask task = ComponentFactory.CreateWithId<DBSaveTask, ComponentWithId, string, TaskCompletionSource<bool>>(component.Id, component, collectionName, tcs);
+			DBSaveTask task = ComponentFactory.CreateWithId<DBSaveTask, ComponentWithId, string, ETTaskCompletionSource<bool>>(component.Id, component, collectionName, tcs);
 			this.tasks[(int)((ulong)task.Id % taskCount)].Add(task);
 
 			return tcs.Task;
 		}
 
-		public Task<bool> AddBatch(List<ComponentWithId> components, string collectionName)
+		public ETTask<bool> AddBatch(List<ComponentWithId> components, string collectionName)
 		{
-			TaskCompletionSource<bool> tcs = new TaskCompletionSource<bool>();
-			DBSaveBatchTask task = ComponentFactory.Create<DBSaveBatchTask, List<ComponentWithId>, string, TaskCompletionSource<bool>>(components, collectionName, tcs);
+			ETTaskCompletionSource<bool> tcs = new ETTaskCompletionSource<bool>();
+			DBSaveBatchTask task = ComponentFactory.Create<DBSaveBatchTask, List<ComponentWithId>, string, ETTaskCompletionSource<bool>>(components, collectionName, tcs);
 			this.tasks[(int)((ulong)task.Id % taskCount)].Add(task);
 			return tcs.Task;
 		}
@@ -95,22 +95,22 @@ namespace ETModel
 			d.Remove(id);
 		}
 
-		public Task<ComponentWithId> Get(string collectionName, long id)
+		public ETTask<ComponentWithId> Get(string collectionName, long id)
 		{
 			ComponentWithId component = GetFromCache(collectionName, id);
 			if (component != null)
 			{
-				return Task.FromResult(component);
+				return ETTask.FromResult(component);
 			}
 
-			TaskCompletionSource<ComponentWithId> tcs = new TaskCompletionSource<ComponentWithId>();
-			DBQueryTask dbQueryTask = ComponentFactory.CreateWithId<DBQueryTask, string, TaskCompletionSource<ComponentWithId>>(id, collectionName, tcs);
+			ETTaskCompletionSource<ComponentWithId> tcs = new ETTaskCompletionSource<ComponentWithId>();
+			DBQueryTask dbQueryTask = ComponentFactory.CreateWithId<DBQueryTask, string, ETTaskCompletionSource<ComponentWithId>>(id, collectionName, tcs);
 			this.tasks[(int)((ulong)id % taskCount)].Add(dbQueryTask);
 
 			return tcs.Task;
 		}
 
-		public Task<List<ComponentWithId>> GetBatch(string collectionName, List<long> idList)
+		public ETTask<List<ComponentWithId>> GetBatch(string collectionName, List<long> idList)
 		{
 			List <ComponentWithId> components = new List<ComponentWithId>();
 			bool isAllInCache = true;
@@ -127,21 +127,21 @@ namespace ETModel
 
 			if (isAllInCache)
 			{
-				return Task.FromResult(components);
+				return ETTask.FromResult(components);
 			}
 
-			TaskCompletionSource<List<ComponentWithId>> tcs = new TaskCompletionSource<List<ComponentWithId>>();
-			DBQueryBatchTask dbQueryBatchTask = ComponentFactory.Create<DBQueryBatchTask, List<long>, string, TaskCompletionSource<List<ComponentWithId>>>(idList, collectionName, tcs);
+			ETTaskCompletionSource<List<ComponentWithId>> tcs = new ETTaskCompletionSource<List<ComponentWithId>>();
+			DBQueryBatchTask dbQueryBatchTask = ComponentFactory.Create<DBQueryBatchTask, List<long>, string, ETTaskCompletionSource<List<ComponentWithId>>>(idList, collectionName, tcs);
 			this.tasks[(int)((ulong)dbQueryBatchTask.Id % taskCount)].Add(dbQueryBatchTask);
 
 			return tcs.Task;
 		}
 		
-		public Task<List<ComponentWithId>> GetJson(string collectionName, string json)
+		public ETTask<List<ComponentWithId>> GetJson(string collectionName, string json)
 		{
-			TaskCompletionSource<List<ComponentWithId>> tcs = new TaskCompletionSource<List<ComponentWithId>>();
+			ETTaskCompletionSource<List<ComponentWithId>> tcs = new ETTaskCompletionSource<List<ComponentWithId>>();
 			
-			DBQueryJsonTask dbQueryJsonTask = ComponentFactory.Create<DBQueryJsonTask, string, string, TaskCompletionSource<List<ComponentWithId>>>(collectionName, json, tcs);
+			DBQueryJsonTask dbQueryJsonTask = ComponentFactory.Create<DBQueryJsonTask, string, string, ETTaskCompletionSource<List<ComponentWithId>>>(collectionName, json, tcs);
 			this.tasks[(int)((ulong)dbQueryJsonTask.Id % taskCount)].Add(dbQueryJsonTask);
 
 			return tcs.Task;

+ 4 - 4
Server/Model/Module/DB/DBQueryBatchTask.cs

@@ -7,9 +7,9 @@ using MongoDB.Driver;
 namespace ETModel
 {
 	[ObjectSystem]
-	public class DbQueryBatchTaskSystem : AwakeSystem<DBQueryBatchTask, List<long>, string, TaskCompletionSource<List<ComponentWithId>>>
+	public class DbQueryBatchTaskSystem : AwakeSystem<DBQueryBatchTask, List<long>, string, ETTaskCompletionSource<List<ComponentWithId>>>
 	{
-		public override void Awake(DBQueryBatchTask self, List<long> idList, string collectionName, TaskCompletionSource<List<ComponentWithId>> tcs)
+		public override void Awake(DBQueryBatchTask self, List<long> idList, string collectionName, ETTaskCompletionSource<List<ComponentWithId>> tcs)
 		{
 			self.IdList = idList;
 			self.CollectionName = collectionName;
@@ -23,9 +23,9 @@ namespace ETModel
 
 		public List<long> IdList { get; set; }
 
-		public TaskCompletionSource<List<ComponentWithId>> Tcs { get; set; }
+		public ETTaskCompletionSource<List<ComponentWithId>> Tcs { get; set; }
 		
-		public override async Task Run()
+		public override async ETTask Run()
 		{
 			DBCacheComponent dbCacheComponent = Game.Scene.GetComponent<DBCacheComponent>();
 			DBComponent dbComponent = Game.Scene.GetComponent<DBComponent>();

+ 4 - 4
Server/Model/Module/DB/DBQueryJsonTask.cs

@@ -6,9 +6,9 @@ using MongoDB.Driver;
 namespace ETModel
 {
 	[ObjectSystem]
-	public class DBQueryJsonTaskAwakeSystem : AwakeSystem<DBQueryJsonTask, string, string, TaskCompletionSource<List<ComponentWithId>>>
+	public class DBQueryJsonTaskAwakeSystem : AwakeSystem<DBQueryJsonTask, string, string, ETTaskCompletionSource<List<ComponentWithId>>>
 	{
-		public override void Awake(DBQueryJsonTask self, string collectionName, string json, TaskCompletionSource<List<ComponentWithId>> tcs)
+		public override void Awake(DBQueryJsonTask self, string collectionName, string json, ETTaskCompletionSource<List<ComponentWithId>> tcs)
 		{
 			self.CollectionName = collectionName;
 			self.Json = json;
@@ -22,9 +22,9 @@ namespace ETModel
 
 		public string Json { get; set; }
 
-		public TaskCompletionSource<List<ComponentWithId>> Tcs { get; set; }
+		public ETTaskCompletionSource<List<ComponentWithId>> Tcs { get; set; }
 		
-		public override async Task Run()
+		public override async ETTask Run()
 		{
 			DBComponent dbComponent = Game.Scene.GetComponent<DBComponent>();
 			try

+ 4 - 4
Server/Model/Module/DB/DBQueryTask.cs

@@ -5,9 +5,9 @@ using MongoDB.Driver;
 namespace ETModel
 {
 	[ObjectSystem]
-	public class DBQueryTaskSystem : AwakeSystem<DBQueryTask, string, TaskCompletionSource<ComponentWithId>>
+	public class DBQueryTaskSystem : AwakeSystem<DBQueryTask, string, ETTaskCompletionSource<ComponentWithId>>
 	{
-		public override void Awake(DBQueryTask self, string collectionName, TaskCompletionSource<ComponentWithId> tcs)
+		public override void Awake(DBQueryTask self, string collectionName, ETTaskCompletionSource<ComponentWithId> tcs)
 		{
 			self.CollectionName = collectionName;
 			self.Tcs = tcs;
@@ -18,9 +18,9 @@ namespace ETModel
 	{
 		public string CollectionName { get; set; }
 
-		public TaskCompletionSource<ComponentWithId> Tcs { get; set; }
+		public ETTaskCompletionSource<ComponentWithId> Tcs { get; set; }
 
-		public override async Task Run()
+		public override async ETTask Run()
 		{
 			DBCacheComponent dbCacheComponent = Game.Scene.GetComponent<DBCacheComponent>();
 			DBComponent dbComponent = Game.Scene.GetComponent<DBComponent>();

+ 4 - 4
Server/Model/Module/DB/DBSaveBatchTask.cs

@@ -7,9 +7,9 @@ using MongoDB.Driver;
 namespace ETModel
 {
 	[ObjectSystem]
-	public class DbSaveBatchTaskSystem : AwakeSystem<DBSaveBatchTask, List<ComponentWithId>, string, TaskCompletionSource<bool>>
+	public class DbSaveBatchTaskSystem : AwakeSystem<DBSaveBatchTask, List<ComponentWithId>, string, ETTaskCompletionSource<bool>>
 	{
-		public override void Awake(DBSaveBatchTask self, List<ComponentWithId> components, string collectionName, TaskCompletionSource<bool> tcs)
+		public override void Awake(DBSaveBatchTask self, List<ComponentWithId> components, string collectionName, ETTaskCompletionSource<bool> tcs)
 		{
 			self.Components = components;
 			self.CollectionName = collectionName;
@@ -23,9 +23,9 @@ namespace ETModel
 
 		public List<ComponentWithId> Components;
 
-		public TaskCompletionSource<bool> Tcs;
+		public ETTaskCompletionSource<bool> Tcs;
 	
-		public override async Task Run()
+		public override async ETTask Run()
 		{
 			DBComponent dbComponent = Game.Scene.GetComponent<DBComponent>();
 

+ 4 - 4
Server/Model/Module/DB/DBSaveTask.cs

@@ -6,9 +6,9 @@ namespace ETModel
 {
 
 	[ObjectSystem]
-	public class DbSaveTaskAwakeSystem : AwakeSystem<DBSaveTask, ComponentWithId, string, TaskCompletionSource<bool>>
+	public class DbSaveTaskAwakeSystem : AwakeSystem<DBSaveTask, ComponentWithId, string, ETTaskCompletionSource<bool>>
 	{
-		public override void Awake(DBSaveTask self, ComponentWithId component, string collectionName, TaskCompletionSource<bool> tcs)
+		public override void Awake(DBSaveTask self, ComponentWithId component, string collectionName, ETTaskCompletionSource<bool> tcs)
 		{
 			self.Component = component;
 			self.CollectionName = collectionName;
@@ -22,9 +22,9 @@ namespace ETModel
 
 		public string CollectionName { get; set; }
 
-		public TaskCompletionSource<bool> Tcs;
+		public ETTaskCompletionSource<bool> Tcs;
 
-		public override async Task Run()
+		public override async ETTask Run()
 		{
 			DBComponent dbComponent = Game.Scene.GetComponent<DBComponent>();
 

+ 2 - 4
Server/Model/Module/DB/DBTask.cs

@@ -1,9 +1,7 @@
-using System.Threading.Tasks;
-
-namespace ETModel
+namespace ETModel
 {
 	public abstract class DBTask : ComponentWithId
 	{
-		public abstract Task Run();
+		public abstract ETTask Run();
 	}
 }

+ 4 - 4
Server/Model/Module/DB/DBTaskQueue.cs

@@ -47,7 +47,7 @@ namespace ETModel
 	{
 		public Queue<DBTask> queue = new Queue<DBTask>();
 
-		public TaskCompletionSource<DBTask> tcs;
+		public ETTaskCompletionSource<DBTask> tcs;
 
 		public void Add(DBTask task)
 		{
@@ -62,15 +62,15 @@ namespace ETModel
 			this.queue.Enqueue(task);
 		}
 
-		public Task<DBTask> Get()
+		public ETTask<DBTask> Get()
 		{
 			if (this.queue.Count > 0)
 			{
 				DBTask task = this.queue.Dequeue();
-				return Task.FromResult(task);
+				return ETTask.FromResult(task);
 			}
 
-			TaskCompletionSource<DBTask> t = new TaskCompletionSource<DBTask>();
+			ETTaskCompletionSource<DBTask> t = new ETTaskCompletionSource<DBTask>();
 			this.tcs = t;
 			return t.Task;
 		}

+ 1 - 1
Server/Model/Module/Http/HttpComponent.cs

@@ -195,7 +195,7 @@ namespace ETModel
 		/// 调用处理方法
 		/// </summary>
 		/// <param name="context"></param>
-		private async Task InvokeHandler(HttpListenerContext context)
+		private async ETTask InvokeHandler(HttpListenerContext context)
 		{
 			context.Response.StatusCode = 404;
 

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

@@ -3,6 +3,7 @@
     <TargetFramework>netcoreapp2.1</TargetFramework>
     <AssemblyName>Model</AssemblyName>
     <RootNamespace>Model</RootNamespace>
+    <LangVersion>7.3</LangVersion>
   </PropertyGroup>
   <PropertyGroup>
     <AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
@@ -19,6 +20,39 @@
   </PropertyGroup>
   <ItemGroup>
     <Compile Remove="Libs\**" />
+    <Compile Include="..\..\Unity\Assets\Model\Base\Async\AsyncUnit.cs">
+      <Link>Base\Async\AsyncUnit.cs</Link>
+    </Compile>
+    <Compile Include="..\..\Unity\Assets\Model\Base\Async\CancellationTokenExtensions.cs">
+      <Link>Base\Async\CancellationTokenExtensions.cs</Link>
+    </Compile>
+    <Compile Include="..\..\Unity\Assets\Model\Base\Async\ETAsyncTaskMethodBuilder.cs">
+      <Link>Base\Async\ETAsyncTaskMethodBuilder.cs</Link>
+    </Compile>
+    <Compile Include="..\..\Unity\Assets\Model\Base\Async\ETAsyncTaskVoidMethodBuilder.cs">
+      <Link>Base\Async\ETAsyncTaskVoidMethodBuilder.cs</Link>
+    </Compile>
+    <Compile Include="..\..\Unity\Assets\Model\Base\Async\ETTask.cs">
+      <Link>Base\Async\ETTask.cs</Link>
+    </Compile>
+    <Compile Include="..\..\Unity\Assets\Model\Base\Async\ETTaskCompletionSource.cs">
+      <Link>Base\Async\ETTaskCompletionSource.cs</Link>
+    </Compile>
+    <Compile Include="..\..\Unity\Assets\Model\Base\Async\ETTaskFactory.cs">
+      <Link>Base\Async\ETTaskFactory.cs</Link>
+    </Compile>
+    <Compile Include="..\..\Unity\Assets\Model\Base\Async\ETTaskVoid.cs">
+      <Link>Base\Async\ETTaskVoid.cs</Link>
+    </Compile>
+    <Compile Include="..\..\Unity\Assets\Model\Base\Async\IAwaiter.cs">
+      <Link>Base\Async\IAwaiter.cs</Link>
+    </Compile>
+    <Compile Include="..\..\Unity\Assets\Model\Base\Async\LazyPromise.cs">
+      <Link>Base\Async\LazyPromise.cs</Link>
+    </Compile>
+    <Compile Include="..\..\Unity\Assets\Model\Base\Async\MoveNextRunner.cs">
+      <Link>Base\Async\MoveNextRunner.cs</Link>
+    </Compile>
     <Compile Include="..\..\Unity\Assets\Model\Base\UnityMath\Color32.cs">
       <Link>Base\UnityMath\Color32.cs</Link>
     </Compile>

+ 1 - 0
Server/ThirdParty/Google.Protobuf/Google.Protobuf.csproj

@@ -4,6 +4,7 @@
     <TargetFramework>netcoreapp2.1</TargetFramework>
     <ApplicationIcon />
     <StartupObject />
+    <LangVersion>7.3</LangVersion>
   </PropertyGroup>
   <PropertyGroup>
     <AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>

+ 1 - 0
Server/ThirdParty/KcpLib/KcpLib.csproj

@@ -1,6 +1,7 @@
 <Project Sdk="Microsoft.NET.Sdk">
   <PropertyGroup>
     <TargetFramework>netcoreapp2.1</TargetFramework>
+    <LangVersion>7.3</LangVersion>
   </PropertyGroup>
   <PropertyGroup>
     <AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>

+ 1 - 0
Server/ThirdParty/MongodbDriver/DotNetCoreDriver/MongoDB.Bson/MongoDB.Bson.csproj

@@ -2,6 +2,7 @@
 
   <PropertyGroup>
     <TargetFramework>netstandard2.0</TargetFramework>
+    <LangVersion>7.3</LangVersion>
   </PropertyGroup>
 
   <PropertyGroup>

+ 1 - 0
Server/ThirdParty/MongodbDriver/DotNetCoreDriver/MongoDB.Driver.Core/MongoDB.Driver.Core.csproj

@@ -2,6 +2,7 @@
 
   <PropertyGroup>
     <TargetFramework>netstandard2.0</TargetFramework>
+    <LangVersion>7.3</LangVersion>
   </PropertyGroup>
 
   <PropertyGroup>

+ 1 - 0
Server/ThirdParty/MongodbDriver/DotNetCoreDriver/MongoDB.Driver/MongoDB.Driver.csproj

@@ -2,6 +2,7 @@
 
   <PropertyGroup>
     <TargetFramework>netstandard2.0</TargetFramework>
+    <LangVersion>7.3</LangVersion>
   </PropertyGroup>
 
   <PropertyGroup>

+ 4 - 4
Unity/Assets/Hotfix/Module/Message/Session.cs

@@ -102,10 +102,10 @@ namespace ETHotfix
 			session.Send(flag, opcode, message);
 		}
 
-		public Task<IResponse> Call(IRequest request)
+		public ETTask<IResponse> Call(IRequest request)
 		{
 			int rpcId = ++RpcId;
-			var tcs = new TaskCompletionSource<IResponse>();
+			var tcs = new ETTaskCompletionSource<IResponse>();
 
 			this.requestCallback[rpcId] = (response) =>
 			{
@@ -130,10 +130,10 @@ namespace ETHotfix
 			return tcs.Task;
 		}
 
-		public Task<IResponse> Call(IRequest request, CancellationToken cancellationToken)
+		public ETTask<IResponse> Call(IRequest request, CancellationToken cancellationToken)
 		{
 			int rpcId = ++RpcId;
-			var tcs = new TaskCompletionSource<IResponse>();
+			var tcs = new ETTaskCompletionSource<IResponse>();
 
 			this.requestCallback[rpcId] = (response) =>
 			{

+ 8 - 0
Unity/Assets/Model/Base/Async.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 4b5c03796fa58a842afafcfb2c4a70b4
+folderAsset: yes
+DefaultImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 12 - 0
Unity/Assets/Model/Base/Async/AsyncMethodBuilderAttribute.cs

@@ -0,0 +1,12 @@
+namespace System.Runtime.CompilerServices
+{
+    public sealed class AsyncMethodBuilderAttribute: Attribute
+    {
+        public Type BuilderType { get; }
+
+        public AsyncMethodBuilderAttribute(Type builderType)
+        {
+            BuilderType = builderType;
+        }
+    }
+}

+ 11 - 0
Unity/Assets/Model/Base/Async/AsyncMethodBuilderAttribute.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 962ae9d28d6b6c74eac6b5ca9c1ad079
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 24 - 0
Unity/Assets/Model/Base/Async/AsyncUnit.cs

@@ -0,0 +1,24 @@
+using System;
+
+namespace ETModel
+{
+    public struct AsyncUnit: IEquatable<AsyncUnit>
+    {
+        public static readonly AsyncUnit Default = new AsyncUnit();
+
+        public override int GetHashCode()
+        {
+            return 0;
+        }
+
+        public bool Equals(AsyncUnit other)
+        {
+            return true;
+        }
+
+        public override string ToString()
+        {
+            return "()";
+        }
+    }
+}

+ 11 - 0
Unity/Assets/Model/Base/Async/AsyncUnit.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 2826256cdc0af9e4b832ff24d04b58da
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 72 - 0
Unity/Assets/Model/Base/Async/CancellationTokenExtensions.cs

@@ -0,0 +1,72 @@
+using System;
+using System.Threading;
+
+namespace ETModel
+{
+    public static class CancellationTokenExtensions
+    {
+        private static readonly Action<object> cancellationTokenCallback = Callback;
+
+        public static (ETTask, CancellationTokenRegistration) ToUniTask(this CancellationToken cts)
+        {
+            if (cts.IsCancellationRequested)
+            {
+                return (ETTask.FromCanceled(cts), default);
+            }
+
+            var promise = new ETTaskCompletionSource<AsyncUnit>();
+            return (promise.Task, cts.RegisterWithoutCaptureExecutionContext(cancellationTokenCallback, promise));
+        }
+
+        private static void Callback(object state)
+        {
+            var promise = (ETTaskCompletionSource<AsyncUnit>) state;
+            promise.TrySetResult(AsyncUnit.Default);
+        }
+
+        public static CancellationTokenRegistration RegisterWithoutCaptureExecutionContext(this CancellationToken cancellationToken, Action callback)
+        {
+            bool restoreFlow = false;
+            if (!ExecutionContext.IsFlowSuppressed())
+            {
+                ExecutionContext.SuppressFlow();
+                restoreFlow = true;
+            }
+
+            try
+            {
+                return cancellationToken.Register(callback, false);
+            }
+            finally
+            {
+                if (restoreFlow)
+                {
+                    ExecutionContext.RestoreFlow();
+                }
+            }
+        }
+
+        public static CancellationTokenRegistration RegisterWithoutCaptureExecutionContext(this CancellationToken cancellationToken,
+        Action<object> callback, object state)
+        {
+            bool restoreFlow = false;
+            if (!ExecutionContext.IsFlowSuppressed())
+            {
+                ExecutionContext.SuppressFlow();
+                restoreFlow = true;
+            }
+
+            try
+            {
+                return cancellationToken.Register(callback, state, false);
+            }
+            finally
+            {
+                if (restoreFlow)
+                {
+                    ExecutionContext.RestoreFlow();
+                }
+            }
+        }
+    }
+}

+ 11 - 0
Unity/Assets/Model/Base/Async/CancellationTokenExtensions.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 1ede9bbc65a28b646b1d1313258bb658
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 267 - 0
Unity/Assets/Model/Base/Async/ETAsyncTaskMethodBuilder.cs

@@ -0,0 +1,267 @@
+using System;
+using System.Diagnostics;
+using System.Runtime.CompilerServices;
+using System.Security;
+
+namespace ETModel
+{
+    public struct ETAsyncTaskMethodBuilder
+    {
+        private ETTaskCompletionSource promise;
+        private Action moveNext;
+
+        // 1. Static Create method.
+        [DebuggerHidden]
+        public static ETAsyncTaskMethodBuilder Create()
+        {
+            ETAsyncTaskMethodBuilder builder = new ETAsyncTaskMethodBuilder();
+            return builder;
+        }
+
+        // 2. TaskLike Task property.
+        [DebuggerHidden]
+        public ETTask Task
+        {
+            get
+            {
+                if (promise != null)
+                {
+                    return promise.Task;
+                }
+
+                if (moveNext == null)
+                {
+                    return ETTask.CompletedTask;
+                }
+
+                this.promise = new ETTaskCompletionSource();
+                return this.promise.Task;
+            }
+        }
+
+        // 3. SetException
+        [DebuggerHidden]
+        public void SetException(Exception exception)
+        {
+            if (promise == null)
+            {
+                promise = new ETTaskCompletionSource();
+            }
+
+            if (exception is OperationCanceledException ex)
+            {
+                promise.TrySetCanceled(ex);
+            }
+            else
+            {
+                promise.TrySetException(exception);
+            }
+        }
+
+        // 4. SetResult
+        [DebuggerHidden]
+        public void SetResult()
+        {
+            if (moveNext == null)
+            {
+            }
+            else
+            {
+                if (promise == null)
+                {
+                    promise = new ETTaskCompletionSource();
+                }
+
+                promise.TrySetResult();
+            }
+        }
+
+        // 5. AwaitOnCompleted
+        [DebuggerHidden]
+        public void AwaitOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine)
+                where TAwaiter : INotifyCompletion
+                where TStateMachine : IAsyncStateMachine
+        {
+            if (moveNext == null)
+            {
+                if (promise == null)
+                {
+                    promise = new ETTaskCompletionSource(); // built future.
+                }
+
+                var runner = new MoveNextRunner<TStateMachine>();
+                moveNext = runner.Run;
+                runner.StateMachine = stateMachine; // set after create delegate.
+            }
+
+            awaiter.OnCompleted(moveNext);
+        }
+
+        // 6. AwaitUnsafeOnCompleted
+        [DebuggerHidden]
+        [SecuritySafeCritical]
+        public void AwaitUnsafeOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine)
+                where TAwaiter : ICriticalNotifyCompletion
+                where TStateMachine : IAsyncStateMachine
+        {
+            if (moveNext == null)
+            {
+                if (promise == null)
+                {
+                    promise = new ETTaskCompletionSource(); // built future.
+                }
+
+                var runner = new MoveNextRunner<TStateMachine>();
+                moveNext = runner.Run;
+                runner.StateMachine = stateMachine; // set after create delegate.
+            }
+
+            awaiter.UnsafeOnCompleted(moveNext);
+        }
+
+        // 7. Start
+        [DebuggerHidden]
+        public void Start<TStateMachine>(ref TStateMachine stateMachine)
+                where TStateMachine : IAsyncStateMachine
+        {
+            stateMachine.MoveNext();
+        }
+
+        // 8. SetStateMachine
+        [DebuggerHidden]
+        public void SetStateMachine(IAsyncStateMachine stateMachine)
+        {
+        }
+    }
+
+    public struct AsyncUniTaskMethodBuilder<T>
+    {
+        private T result;
+        private ETTaskCompletionSource<T> promise;
+        private Action moveNext;
+
+        // 1. Static Create method.
+        [DebuggerHidden]
+        public static AsyncUniTaskMethodBuilder<T> Create()
+        {
+            var builder = new AsyncUniTaskMethodBuilder<T>();
+            return builder;
+        }
+
+        // 2. TaskLike Task property.
+        [DebuggerHidden]
+        public ETTask<T> Task
+        {
+            get
+            {
+                if (promise != null)
+                {
+                    return new ETTask<T>(promise);
+                }
+
+                if (moveNext == null)
+                {
+                    return new ETTask<T>(result);
+                }
+
+                this.promise = new ETTaskCompletionSource<T>();
+                return new ETTask<T>(this.promise);
+            }
+        }
+
+        // 3. SetException
+        [DebuggerHidden]
+        public void SetException(Exception exception)
+        {
+            if (promise == null)
+            {
+                promise = new ETTaskCompletionSource<T>();
+            }
+
+            if (exception is OperationCanceledException ex)
+            {
+                promise.TrySetCanceled(ex);
+            }
+            else
+            {
+                promise.TrySetException(exception);
+            }
+        }
+
+        // 4. SetResult
+        [DebuggerHidden]
+        public void SetResult(T result)
+        {
+            if (moveNext == null)
+            {
+                this.result = result;
+            }
+            else
+            {
+                if (promise == null)
+                {
+                    promise = new ETTaskCompletionSource<T>();
+                }
+
+                promise.TrySetResult(result);
+            }
+        }
+
+        // 5. AwaitOnCompleted
+        [DebuggerHidden]
+        public void AwaitOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine)
+                where TAwaiter : INotifyCompletion
+                where TStateMachine : IAsyncStateMachine
+        {
+            if (moveNext == null)
+            {
+                if (promise == null)
+                {
+                    promise = new ETTaskCompletionSource<T>(); // built future.
+                }
+
+                var runner = new MoveNextRunner<TStateMachine>();
+                moveNext = runner.Run;
+                runner.StateMachine = stateMachine; // set after create delegate.
+            }
+
+            awaiter.OnCompleted(moveNext);
+        }
+
+        // 6. AwaitUnsafeOnCompleted
+        [DebuggerHidden]
+        [SecuritySafeCritical]
+        public void AwaitUnsafeOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine)
+                where TAwaiter : ICriticalNotifyCompletion
+                where TStateMachine : IAsyncStateMachine
+        {
+            if (moveNext == null)
+            {
+                if (promise == null)
+                {
+                    promise = new ETTaskCompletionSource<T>(); // built future.
+                }
+
+                var runner = new MoveNextRunner<TStateMachine>();
+                moveNext = runner.Run;
+                runner.StateMachine = stateMachine; // set after create delegate.
+            }
+
+            awaiter.UnsafeOnCompleted(moveNext);
+        }
+
+        // 7. Start
+        [DebuggerHidden]
+        public void Start<TStateMachine>(ref TStateMachine stateMachine)
+                where TStateMachine : IAsyncStateMachine
+        {
+            stateMachine.MoveNext();
+        }
+
+        // 8. SetStateMachine
+        [DebuggerHidden]
+        public void SetStateMachine(IAsyncStateMachine stateMachine)
+        {
+        }
+    }
+}

+ 11 - 0
Unity/Assets/Model/Base/Async/ETAsyncTaskMethodBuilder.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 7680d001d37983d4594019f0dfdf29b9
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 83 - 0
Unity/Assets/Model/Base/Async/ETAsyncTaskVoidMethodBuilder.cs

@@ -0,0 +1,83 @@
+using System;
+using System.Diagnostics;
+using System.Runtime.CompilerServices;
+using System.Security;
+
+namespace ETModel
+{
+    public struct ETAsyncTaskVoidMethodBuilder
+    {
+        private Action moveNext;
+
+        // 1. Static Create method.
+        [DebuggerHidden]
+        public static ETAsyncTaskVoidMethodBuilder Create()
+        {
+            ETAsyncTaskVoidMethodBuilder builder = new ETAsyncTaskVoidMethodBuilder();
+            return builder;
+        }
+
+        // 2. TaskLike Task property(void)
+        public ETTaskVoid Task => default;
+
+        // 3. SetException
+        [DebuggerHidden]
+        public void SetException(Exception exception)
+        {
+        }
+
+        // 4. SetResult
+        [DebuggerHidden]
+        public void SetResult()
+        {
+            // do nothing
+        }
+
+        // 5. AwaitOnCompleted
+        [DebuggerHidden]
+        public void AwaitOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine)
+                where TAwaiter : INotifyCompletion
+                where TStateMachine : IAsyncStateMachine
+        {
+            if (moveNext == null)
+            {
+                var runner = new MoveNextRunner<TStateMachine>();
+                moveNext = runner.Run;
+                runner.StateMachine = stateMachine; // set after create delegate.
+            }
+
+            awaiter.OnCompleted(moveNext);
+        }
+
+        // 6. AwaitUnsafeOnCompleted
+        [DebuggerHidden]
+        [SecuritySafeCritical]
+        public void AwaitUnsafeOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine)
+                where TAwaiter : ICriticalNotifyCompletion
+                where TStateMachine : IAsyncStateMachine
+        {
+            if (moveNext == null)
+            {
+                var runner = new MoveNextRunner<TStateMachine>();
+                moveNext = runner.Run;
+                runner.StateMachine = stateMachine; // set after create delegate.
+            }
+
+            awaiter.UnsafeOnCompleted(moveNext);
+        }
+
+        // 7. Start
+        [DebuggerHidden]
+        public void Start<TStateMachine>(ref TStateMachine stateMachine)
+                where TStateMachine : IAsyncStateMachine
+        {
+            stateMachine.MoveNext();
+        }
+
+        // 8. SetStateMachine
+        [DebuggerHidden]
+        public void SetStateMachine(IAsyncStateMachine stateMachine)
+        {
+        }
+    }
+}

+ 11 - 0
Unity/Assets/Model/Base/Async/ETAsyncTaskVoidMethodBuilder.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 390ef7e019b703f46900fcc7dde998f1
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 458 - 0
Unity/Assets/Model/Base/Async/ETTask.cs

@@ -0,0 +1,458 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Runtime.CompilerServices;
+
+namespace ETModel
+{
+    /// <summary>
+    /// Lightweight unity specified task-like object.
+    /// </summary>
+    [AsyncMethodBuilder(typeof (ETAsyncTaskMethodBuilder))]
+    public partial struct ETTask: IEquatable<ETTask>
+    {
+        private static readonly ETTask<AsyncUnit> DefaultAsyncUnitTask = new ETTask<AsyncUnit>(AsyncUnit.Default);
+
+        private readonly IAwaiter awaiter;
+
+        [DebuggerHidden]
+        public ETTask(IAwaiter awaiter)
+        {
+            this.awaiter = awaiter;
+        }
+
+        [DebuggerHidden]
+        public ETTask(Func<ETTask> factory)
+        {
+            this.awaiter = new LazyPromise(factory);
+        }
+
+        [DebuggerHidden]
+        public AwaiterStatus Status => awaiter?.Status ?? AwaiterStatus.Succeeded;
+
+        [DebuggerHidden]
+        public bool IsCompleted => awaiter?.IsCompleted ?? true;
+
+        [DebuggerHidden]
+        public void GetResult()
+        {
+            if (awaiter != null)
+            {
+                awaiter.GetResult();
+            }
+        }
+
+        [DebuggerHidden]
+        public Awaiter GetAwaiter()
+        {
+            return new Awaiter(this);
+        }
+
+        /// <summary>
+        /// returns (bool IsCanceled) instead of throws OperationCanceledException.
+        /// </summary>
+        public ETTask<bool> SuppressCancellationThrow()
+        {
+            AwaiterStatus status = Status;
+            switch (status)
+            {
+                case AwaiterStatus.Succeeded:
+                    return CompletedTasks.False;
+                case AwaiterStatus.Canceled:
+                    return CompletedTasks.True;
+                default:
+                    return new ETTask<bool>(new IsCanceledAwaiter(this.awaiter));
+            }
+        }
+
+        public bool Equals(ETTask other)
+        {
+            if (this.awaiter == null && other.awaiter == null)
+            {
+                return true;
+            }
+
+            if (this.awaiter != null && other.awaiter != null)
+            {
+                return this.awaiter == other.awaiter;
+            }
+
+            return false;
+        }
+
+        public override int GetHashCode()
+        {
+            if (this.awaiter == null)
+            {
+                return 0;
+            }
+
+            return this.awaiter.GetHashCode();
+        }
+
+        public override string ToString()
+        {
+            return this.awaiter == null? "()"
+                    : this.awaiter.Status == AwaiterStatus.Succeeded? "()"
+                    : "(" + this.awaiter.Status + ")";
+        }
+
+        public static implicit operator ETTask<AsyncUnit>(ETTask task)
+        {
+            if (task.awaiter == null)
+            {
+                return DefaultAsyncUnitTask;
+            }
+
+            if (task.awaiter.IsCompleted)
+            {
+                return DefaultAsyncUnitTask;
+            }
+
+            // UniTask<T> -> UniTask is free but UniTask -> UniTask<T> requires wrapping cost.
+            return new ETTask<AsyncUnit>(new AsyncUnitAwaiter(task.awaiter));
+
+        }
+
+        private class AsyncUnitAwaiter: IAwaiter<AsyncUnit>
+        {
+            private readonly IAwaiter awaiter;
+
+            public AsyncUnitAwaiter(IAwaiter awaiter)
+            {
+                this.awaiter = awaiter;
+            }
+
+            public bool IsCompleted => awaiter.IsCompleted;
+
+            public AwaiterStatus Status => awaiter.Status;
+
+            public AsyncUnit GetResult()
+            {
+                awaiter.GetResult();
+                return AsyncUnit.Default;
+            }
+
+            public void OnCompleted(Action continuation)
+            {
+                awaiter.OnCompleted(continuation);
+            }
+
+            public void UnsafeOnCompleted(Action continuation)
+            {
+                awaiter.UnsafeOnCompleted(continuation);
+            }
+
+            void IAwaiter.GetResult()
+            {
+                awaiter.GetResult();
+            }
+        }
+
+        private class IsCanceledAwaiter: IAwaiter<bool>
+        {
+            private readonly IAwaiter awaiter;
+
+            public IsCanceledAwaiter(IAwaiter awaiter)
+            {
+                this.awaiter = awaiter;
+            }
+
+            public bool IsCompleted => awaiter.IsCompleted;
+
+            public AwaiterStatus Status => awaiter.Status;
+
+            public bool GetResult()
+            {
+                if (awaiter.Status == AwaiterStatus.Canceled)
+                {
+                    return true;
+                }
+
+                awaiter.GetResult();
+                return false;
+            }
+
+            public void OnCompleted(Action continuation)
+            {
+                awaiter.OnCompleted(continuation);
+            }
+
+            public void UnsafeOnCompleted(Action continuation)
+            {
+                awaiter.UnsafeOnCompleted(continuation);
+            }
+
+            void IAwaiter.GetResult()
+            {
+                awaiter.GetResult();
+            }
+        }
+
+        public struct Awaiter: IAwaiter
+        {
+            private readonly ETTask task;
+
+            [DebuggerHidden]
+            public Awaiter(ETTask task)
+            {
+                this.task = task;
+            }
+
+            [DebuggerHidden]
+            public bool IsCompleted => task.IsCompleted;
+
+            [DebuggerHidden]
+            public AwaiterStatus Status => task.Status;
+
+            [DebuggerHidden]
+            public void GetResult()
+            {
+                task.GetResult();
+            }
+
+            [DebuggerHidden]
+            public void OnCompleted(Action continuation)
+            {
+                if (task.awaiter != null)
+                {
+                    task.awaiter.OnCompleted(continuation);
+                }
+                else
+                {
+                    continuation();
+                }
+            }
+
+            [DebuggerHidden]
+            public void UnsafeOnCompleted(Action continuation)
+            {
+                if (task.awaiter != null)
+                {
+                    task.awaiter.UnsafeOnCompleted(continuation);
+                }
+                else
+                {
+                    continuation();
+                }
+            }
+        }
+    }
+
+    /// <summary>
+    /// Lightweight unity specified task-like object.
+    /// </summary>
+    [AsyncMethodBuilder(typeof (AsyncUniTaskMethodBuilder<>))]
+    public struct ETTask<T>: IEquatable<ETTask<T>>
+    {
+        private readonly T result;
+        private readonly IAwaiter<T> awaiter;
+
+        [DebuggerHidden]
+        public ETTask(T result)
+        {
+            this.result = result;
+            this.awaiter = null;
+        }
+
+        [DebuggerHidden]
+        public ETTask(IAwaiter<T> awaiter)
+        {
+            this.result = default;
+            this.awaiter = awaiter;
+        }
+
+        [DebuggerHidden]
+        public ETTask(Func<ETTask<T>> factory)
+        {
+            this.result = default;
+            this.awaiter = new LazyPromise<T>(factory);
+        }
+
+        [DebuggerHidden]
+        public AwaiterStatus Status => awaiter?.Status ?? AwaiterStatus.Succeeded;
+
+        [DebuggerHidden]
+        public bool IsCompleted => awaiter?.IsCompleted ?? true;
+
+        [DebuggerHidden]
+        public T Result
+        {
+            get
+            {
+                if (awaiter == null)
+                {
+                    return result;
+                }
+
+                return this.awaiter.GetResult();
+            }
+        }
+
+        [DebuggerHidden]
+        public Awaiter GetAwaiter()
+        {
+            return new Awaiter(this);
+        }
+
+        /// <summary>
+        /// returns (bool IsCanceled, T Result) instead of throws OperationCanceledException.
+        /// </summary>
+        public ETTask<(bool IsCanceled, T Result)> SuppressCancellationThrow()
+        {
+            var status = Status;
+            if (status == AwaiterStatus.Succeeded)
+            {
+                return new ETTask<(bool, T)>((false, Result));
+            }
+
+            if (status == AwaiterStatus.Canceled)
+            {
+                return new ETTask<(bool, T)>((true, default));
+            }
+
+            return new ETTask<(bool, T)>(new IsCanceledAwaiter(awaiter));
+        }
+
+        public bool Equals(ETTask<T> other)
+        {
+            if (this.awaiter == null && other.awaiter == null)
+            {
+                return EqualityComparer<T>.Default.Equals(this.result, other.result);
+            }
+
+            if (this.awaiter != null && other.awaiter != null)
+            {
+                return this.awaiter == other.awaiter;
+            }
+
+            return false;
+        }
+
+        public override int GetHashCode()
+        {
+            if (this.awaiter == null)
+            {
+                if (result == null)
+                {
+                    return 0;
+                }
+
+                return result.GetHashCode();
+            }
+
+            return this.awaiter.GetHashCode();
+        }
+
+        public override string ToString()
+        {
+            return this.awaiter == null? result.ToString()
+                    : this.awaiter.Status == AwaiterStatus.Succeeded? this.awaiter.GetResult().ToString()
+                    : "(" + this.awaiter.Status + ")";
+        }
+
+        public static implicit operator ETTask(ETTask<T> task)
+        {
+            if (task.awaiter != null)
+            {
+                return new ETTask(task.awaiter);
+            }
+
+            return new ETTask();
+        }
+
+        private class IsCanceledAwaiter: IAwaiter<(bool, T)>
+        {
+            private readonly IAwaiter<T> awaiter;
+
+            public IsCanceledAwaiter(IAwaiter<T> awaiter)
+            {
+                this.awaiter = awaiter;
+            }
+
+            public bool IsCompleted => awaiter.IsCompleted;
+
+            public AwaiterStatus Status => awaiter.Status;
+
+            public (bool, T) GetResult()
+            {
+                if (awaiter.Status == AwaiterStatus.Canceled)
+                {
+                    return (true, default);
+                }
+
+                return (false, awaiter.GetResult());
+            }
+
+            public void OnCompleted(Action continuation)
+            {
+                awaiter.OnCompleted(continuation);
+            }
+
+            public void UnsafeOnCompleted(Action continuation)
+            {
+                awaiter.UnsafeOnCompleted(continuation);
+            }
+
+            void IAwaiter.GetResult()
+            {
+                awaiter.GetResult();
+            }
+        }
+
+        public struct Awaiter: IAwaiter<T>
+        {
+            private readonly ETTask<T> task;
+
+            [DebuggerHidden]
+            public Awaiter(ETTask<T> task)
+            {
+                this.task = task;
+            }
+
+            [DebuggerHidden]
+            public bool IsCompleted => task.IsCompleted;
+
+            [DebuggerHidden]
+            public AwaiterStatus Status => task.Status;
+
+            [DebuggerHidden]
+            void IAwaiter.GetResult()
+            {
+                GetResult();
+            }
+
+            [DebuggerHidden]
+            public T GetResult()
+            {
+                return task.Result;
+            }
+
+            [DebuggerHidden]
+            public void OnCompleted(Action continuation)
+            {
+                if (task.awaiter != null)
+                {
+                    task.awaiter.OnCompleted(continuation);
+                }
+                else
+                {
+                    continuation();
+                }
+            }
+
+            [DebuggerHidden]
+            public void UnsafeOnCompleted(Action continuation)
+            {
+                if (task.awaiter != null)
+                {
+                    task.awaiter.UnsafeOnCompleted(continuation);
+                }
+                else
+                {
+                    continuation();
+                }
+            }
+        }
+    }
+}

+ 11 - 0
Unity/Assets/Model/Base/Async/ETTask.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 624636d415540b94b934cf1931b5c281
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 421 - 0
Unity/Assets/Model/Base/Async/ETTaskCompletionSource.cs

@@ -0,0 +1,421 @@
+using System;
+using System.Collections.Generic;
+using System.Runtime.CompilerServices;
+using System.Runtime.ExceptionServices;
+using System.Threading;
+
+namespace ETModel
+{
+    internal class ExceptionHolder
+    {
+        private readonly ExceptionDispatchInfo exception;
+        private bool calledGet;
+
+        public ExceptionHolder(ExceptionDispatchInfo exception)
+        {
+            this.exception = exception;
+        }
+
+        public ExceptionDispatchInfo GetException()
+        {
+            if (calledGet)
+            {
+                return this.exception;
+            }
+
+            this.calledGet = true;
+            GC.SuppressFinalize(this);
+
+            return exception;
+        }
+    }
+
+    public interface IResolvePromise
+    {
+        bool TrySetResult();
+    }
+
+    public interface IResolvePromise<T>
+    {
+        bool TrySetResult(T value);
+    }
+
+    public interface IRejectPromise
+    {
+        bool TrySetException(Exception e);
+    }
+
+    public interface ICancelPromise
+    {
+        bool TrySetCanceled();
+    }
+
+    public interface IPromise<T>: IResolvePromise<T>, IRejectPromise, ICancelPromise
+    {
+    }
+
+    public interface IPromise: IResolvePromise, IRejectPromise, ICancelPromise
+    {
+    }
+
+    public class ETTaskCompletionSource: IAwaiter, IPromise
+    {
+        // State(= AwaiterStatus)
+        private const int Pending = 0;
+        private const int Succeeded = 1;
+        private const int Faulted = 2;
+        private const int Canceled = 3;
+
+        private int state;
+        private ExceptionHolder exception;
+        private object continuation; // action or list
+
+        AwaiterStatus IAwaiter.Status => (AwaiterStatus) state;
+
+        bool IAwaiter.IsCompleted => state != Pending;
+
+        public ETTask Task => new ETTask(this);
+
+        void IAwaiter.GetResult()
+        {
+            switch (this.state)
+            {
+                case Succeeded:
+                    return;
+                case Faulted:
+                    this.exception.GetException().Throw();
+                    return;
+                case Canceled:
+                {
+                    if (this.exception != null)
+                    {
+                        this.exception.GetException().Throw(); // guranteed operation canceled exception.
+                    }
+
+                    throw new OperationCanceledException();
+                }
+                default:
+                    throw new NotSupportedException("UniTask does not allow call GetResult directly when task not completed. Please use 'await'.");
+            }
+        }
+
+        void ICriticalNotifyCompletion.UnsafeOnCompleted(Action action)
+        {
+            if (Interlocked.CompareExchange(ref continuation, action, null) == null)
+            {
+                if (state != Pending)
+                {
+                    TryInvokeContinuation();
+                }
+            }
+            else
+            {
+                object c = continuation;
+                if (c is Action action1)
+                {
+                    var list = new List<Action>();
+                    list.Add(action1);
+                    list.Add(action);
+                    if (Interlocked.CompareExchange(ref continuation, list, action1) == action1)
+                    {
+                        goto TRYINVOKE;
+                    }
+                }
+
+                var l = (List<Action>) continuation;
+                lock (l)
+                {
+                    l.Add(action);
+                }
+
+                TRYINVOKE:
+                if (state != Pending)
+                {
+                    TryInvokeContinuation();
+                }
+            }
+        }
+
+        private void TryInvokeContinuation()
+        {
+            object c = Interlocked.Exchange(ref continuation, null);
+            if (c == null)
+            {
+                return;
+            }
+
+            if (c is Action action)
+            {
+                action.Invoke();
+            }
+            else
+            {
+                var l = (List<Action>) c;
+                int cnt = l.Count;
+                for (int i = 0; i < cnt; i++)
+                {
+                    l[i].Invoke();
+                }
+            }
+        }
+
+        public void SetResult()
+        {
+            if (this.TrySetResult())
+            {
+                return;
+            }
+
+            throw new InvalidOperationException("TaskT_TransitionToFinal_AlreadyCompleted");
+        }
+
+        public void SetException(Exception e)
+        {
+            if (this.TrySetException(e))
+            {
+                return;
+            }
+
+            throw new InvalidOperationException("TaskT_TransitionToFinal_AlreadyCompleted");
+        }
+
+        public bool TrySetResult()
+        {
+            if (Interlocked.CompareExchange(ref this.state, Succeeded, Pending) != Pending)
+            {
+                return false;
+            }
+
+            this.TryInvokeContinuation();
+            return true;
+
+        }
+
+        public bool TrySetException(Exception e)
+        {
+            if (Interlocked.CompareExchange(ref this.state, Faulted, Pending) != Pending)
+            {
+                return false;
+            }
+
+            this.exception = new ExceptionHolder(ExceptionDispatchInfo.Capture(e));
+            this.TryInvokeContinuation();
+            return true;
+
+        }
+
+        public bool TrySetCanceled()
+        {
+            if (Interlocked.CompareExchange(ref this.state, Canceled, Pending) != Pending)
+            {
+                return false;
+            }
+
+            this.TryInvokeContinuation();
+            return true;
+
+        }
+
+        public bool TrySetCanceled(OperationCanceledException e)
+        {
+            if (Interlocked.CompareExchange(ref this.state, Canceled, Pending) != Pending)
+            {
+                return false;
+            }
+
+            this.exception = new ExceptionHolder(ExceptionDispatchInfo.Capture(e));
+            this.TryInvokeContinuation();
+            return true;
+
+        }
+
+        void INotifyCompletion.OnCompleted(Action action)
+        {
+            ((ICriticalNotifyCompletion) this).UnsafeOnCompleted(action);
+        }
+    }
+
+    public class ETTaskCompletionSource<T>: IAwaiter<T>, IPromise<T>
+    {
+        // State(= AwaiterStatus)
+        private const int Pending = 0;
+        private const int Succeeded = 1;
+        private const int Faulted = 2;
+        private const int Canceled = 3;
+
+        private int state;
+        private T value;
+        private ExceptionHolder exception;
+        private object continuation; // action or list
+
+        bool IAwaiter.IsCompleted => state != Pending;
+
+        public ETTask<T> Task => new ETTask<T>(this);
+        public ETTask UnitTask => new ETTask(this);
+
+        AwaiterStatus IAwaiter.Status => (AwaiterStatus) state;
+
+        T IAwaiter<T>.GetResult()
+        {
+            switch (this.state)
+            {
+                case Succeeded:
+                    return this.value;
+                case Faulted:
+                    this.exception.GetException().Throw();
+                    return default;
+                case Canceled:
+                {
+                    if (this.exception != null)
+                    {
+                        this.exception.GetException().Throw(); // guranteed operation canceled exception.
+                    }
+
+                    throw new OperationCanceledException();
+                }
+                default:
+                    throw new NotSupportedException("UniTask does not allow call GetResult directly when task not completed. Please use 'await'.");
+            }
+        }
+
+        void ICriticalNotifyCompletion.UnsafeOnCompleted(Action action)
+        {
+            if (Interlocked.CompareExchange(ref continuation, action, null) == null)
+            {
+                if (state != Pending)
+                {
+                    TryInvokeContinuation();
+                }
+            }
+            else
+            {
+                var c = continuation;
+                if (c is Action action1)
+                {
+                    var list = new List<Action>();
+                    list.Add(action1);
+                    list.Add(action);
+                    if (Interlocked.CompareExchange(ref continuation, list, action1) == action1)
+                    {
+                        goto TRYINVOKE;
+                    }
+                }
+
+                var l = (List<Action>) continuation;
+                lock (l)
+                {
+                    l.Add(action);
+                }
+
+                TRYINVOKE:
+                if (state != Pending)
+                {
+                    TryInvokeContinuation();
+                }
+            }
+        }
+
+        private void TryInvokeContinuation()
+        {
+            object c = Interlocked.Exchange(ref continuation, null);
+            if (c == null)
+            {
+                return;
+            }
+
+            if (c is Action action)
+            {
+                action.Invoke();
+                return;
+            }
+
+            var l = (List<Action>) c;
+            int cnt = l.Count;
+            for (int i = 0; i < cnt; i++)
+            {
+                l[i].Invoke();
+            }
+        }
+
+        public void SetResult(T result)
+        {
+            if (this.TrySetResult(result))
+            {
+                return;
+            }
+
+            throw new InvalidOperationException("TaskT_TransitionToFinal_AlreadyCompleted");
+        }
+
+        public void SetException(Exception e)
+        {
+            if (this.TrySetException(e))
+            {
+                return;
+            }
+
+            throw new InvalidOperationException("TaskT_TransitionToFinal_AlreadyCompleted");
+        }
+
+        public bool TrySetResult(T result)
+        {
+            if (Interlocked.CompareExchange(ref this.state, Succeeded, Pending) != Pending)
+            {
+                return false;
+            }
+
+            this.value = result;
+            this.TryInvokeContinuation();
+            return true;
+
+        }
+
+        public bool TrySetException(Exception e)
+        {
+            if (Interlocked.CompareExchange(ref this.state, Faulted, Pending) != Pending)
+            {
+                return false;
+            }
+
+            this.exception = new ExceptionHolder(ExceptionDispatchInfo.Capture(e));
+            this.TryInvokeContinuation();
+            return true;
+
+        }
+
+        public bool TrySetCanceled()
+        {
+            if (Interlocked.CompareExchange(ref this.state, Canceled, Pending) != Pending)
+            {
+                return false;
+            }
+
+            this.TryInvokeContinuation();
+            return true;
+
+        }
+
+        public bool TrySetCanceled(OperationCanceledException e)
+        {
+            if (Interlocked.CompareExchange(ref this.state, Canceled, Pending) != Pending)
+            {
+                return false;
+            }
+
+            this.exception = new ExceptionHolder(ExceptionDispatchInfo.Capture(e));
+            this.TryInvokeContinuation();
+            return true;
+
+        }
+
+        void IAwaiter.GetResult()
+        {
+            ((IAwaiter<T>) this).GetResult();
+        }
+
+        void INotifyCompletion.OnCompleted(Action action)
+        {
+            ((ICriticalNotifyCompletion) this).UnsafeOnCompleted(action);
+        }
+    }
+}

+ 11 - 0
Unity/Assets/Model/Base/Async/ETTaskCompletionSource.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 371afc623684c4643ac84af2c4d5aae1
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 87 - 0
Unity/Assets/Model/Base/Async/ETTaskFactory.cs

@@ -0,0 +1,87 @@
+using System;
+using System.Threading;
+
+namespace ETModel
+{
+    public partial struct ETTask
+    {
+        private static readonly ETTask CanceledUniTask = new Func<ETTask>(() =>
+        {
+            var promise = new ETTaskCompletionSource<AsyncUnit>();
+            promise.TrySetCanceled();
+            return new ETTask(promise);
+        })();
+
+        public static ETTask CompletedTask => new ETTask();
+
+        public static ETTask FromException(Exception ex)
+        {
+            var promise = new ETTaskCompletionSource<AsyncUnit>();
+            promise.TrySetException(ex);
+            return new ETTask(promise);
+        }
+
+        public static ETTask<T> FromException<T>(Exception ex)
+        {
+            var promise = new ETTaskCompletionSource<T>();
+            promise.TrySetException(ex);
+            return new ETTask<T>(promise);
+        }
+
+        public static ETTask<T> FromResult<T>(T value)
+        {
+            return new ETTask<T>(value);
+        }
+
+        public static ETTask FromCanceled()
+        {
+            return CanceledUniTask;
+        }
+
+        public static ETTask<T> FromCanceled<T>()
+        {
+            return CanceledUniTaskCache<T>.Task;
+        }
+
+        public static ETTask FromCanceled(CancellationToken token)
+        {
+            var promise = new ETTaskCompletionSource<AsyncUnit>();
+            promise.TrySetException(new OperationCanceledException(token));
+            return new ETTask(promise);
+        }
+
+        public static ETTask<T> FromCanceled<T>(CancellationToken token)
+        {
+            var promise = new ETTaskCompletionSource<T>();
+            promise.TrySetException(new OperationCanceledException(token));
+            return new ETTask<T>(promise);
+        }
+
+        /// <summary>shorthand of new UniTask[T](Func[UniTask[T]] factory)</summary>
+        public static ETTask<T> Lazy<T>(Func<ETTask<T>> factory)
+        {
+            return new ETTask<T>(factory);
+        }
+
+        private static class CanceledUniTaskCache<T>
+        {
+            public static readonly ETTask<T> Task;
+
+            static CanceledUniTaskCache()
+            {
+                var promise = new ETTaskCompletionSource<T>();
+                promise.TrySetCanceled();
+                Task = new ETTask<T>(promise);
+            }
+        }
+    }
+
+    internal static class CompletedTasks
+    {
+        public static readonly ETTask<bool> True = ETTask.FromResult(true);
+        public static readonly ETTask<bool> False = ETTask.FromResult(false);
+        public static readonly ETTask<int> Zero = ETTask.FromResult(0);
+        public static readonly ETTask<int> MinusOne = ETTask.FromResult(-1);
+        public static readonly ETTask<int> One = ETTask.FromResult(1);
+    }
+}

+ 11 - 0
Unity/Assets/Model/Base/Async/ETTaskFactory.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 5799679ead03f044a8db11144a25e609
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 42 - 0
Unity/Assets/Model/Base/Async/ETTaskVoid.cs

@@ -0,0 +1,42 @@
+using System;
+using System.Diagnostics;
+using System.Runtime.CompilerServices;
+
+namespace ETModel
+{
+    [AsyncMethodBuilder(typeof (ETAsyncTaskVoidMethodBuilder))]
+    public struct ETTaskVoid
+    {
+        public void Forget()
+        {
+        }
+
+        [DebuggerHidden]
+        public Awaiter GetAwaiter()
+        {
+            return new Awaiter();
+        }
+
+        public struct Awaiter: ICriticalNotifyCompletion
+        {
+            [DebuggerHidden]
+            public bool IsCompleted => true;
+
+            [DebuggerHidden]
+            public void GetResult()
+            {
+                throw new Exception("UniTask can't await, always fire-and-forget. use Forget instead of await.");
+            }
+
+            [DebuggerHidden]
+            public void OnCompleted(Action continuation)
+            {
+            }
+
+            [DebuggerHidden]
+            public void UnsafeOnCompleted(Action continuation)
+            {
+            }
+        }
+    }
+}

+ 11 - 0
Unity/Assets/Model/Base/Async/ETTaskVoid.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 9157caacd834b5848b11553a6ea73494
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 62 - 0
Unity/Assets/Model/Base/Async/IAwaiter.cs

@@ -0,0 +1,62 @@
+using System.Runtime.CompilerServices;
+
+namespace ETModel
+{
+    public enum AwaiterStatus
+    {
+        /// <summary>The operation has not yet completed.</summary>
+        Pending = 0,
+
+        /// <summary>The operation completed successfully.</summary>
+        Succeeded = 1,
+
+        /// <summary>The operation completed with an error.</summary>
+        Faulted = 2,
+
+        /// <summary>The operation completed due to cancellation.</summary>
+        Canceled = 3
+    }
+
+    public interface IAwaiter: ICriticalNotifyCompletion
+    {
+        AwaiterStatus Status { get; }
+        bool IsCompleted { get; }
+        void GetResult();
+    }
+
+    public interface IAwaiter<out T>: IAwaiter
+    {
+        new T GetResult();
+    }
+
+    public static class AwaiterStatusExtensions
+    {
+        /// <summary>!= Pending.</summary>
+        [MethodImpl(MethodImplOptions.AggressiveInlining)]
+        public static bool IsCompleted(this AwaiterStatus status)
+        {
+            return status != AwaiterStatus.Pending;
+        }
+
+        /// <summary>== Succeeded.</summary>
+        [MethodImpl(MethodImplOptions.AggressiveInlining)]
+        public static bool IsCompletedSuccessfully(this AwaiterStatus status)
+        {
+            return status == AwaiterStatus.Succeeded;
+        }
+
+        /// <summary>== Canceled.</summary>
+        [MethodImpl(MethodImplOptions.AggressiveInlining)]
+        public static bool IsCanceled(this AwaiterStatus status)
+        {
+            return status == AwaiterStatus.Canceled;
+        }
+
+        /// <summary>== Faulted.</summary>
+        [MethodImpl(MethodImplOptions.AggressiveInlining)]
+        public static bool IsFaulted(this AwaiterStatus status)
+        {
+            return status == AwaiterStatus.Faulted;
+        }
+    }
+}

+ 11 - 0
Unity/Assets/Model/Base/Async/IAwaiter.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: d48c67734d0468148be856dbd3051d19
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 125 - 0
Unity/Assets/Model/Base/Async/LazyPromise.cs

@@ -0,0 +1,125 @@
+using System;
+using System.Threading;
+
+namespace ETModel
+{
+    internal sealed class LazyPromise: IAwaiter
+    {
+        private Func<ETTask> factory;
+        private ETTask value;
+
+        public LazyPromise(Func<ETTask> factory)
+        {
+            this.factory = factory;
+        }
+
+        private void Create()
+        {
+            var f = Interlocked.Exchange(ref factory, null);
+            if (f != null)
+            {
+                value = f();
+            }
+        }
+
+        public bool IsCompleted
+        {
+            get
+            {
+                Create();
+                return value.IsCompleted;
+            }
+        }
+
+        public AwaiterStatus Status
+        {
+            get
+            {
+                Create();
+                return value.Status;
+            }
+        }
+
+        public void GetResult()
+        {
+            Create();
+            value.GetResult();
+        }
+
+        void IAwaiter.GetResult()
+        {
+            GetResult();
+        }
+
+        public void UnsafeOnCompleted(Action continuation)
+        {
+            Create();
+            value.GetAwaiter().UnsafeOnCompleted(continuation);
+        }
+
+        public void OnCompleted(Action continuation)
+        {
+            UnsafeOnCompleted(continuation);
+        }
+    }
+
+    internal sealed class LazyPromise<T>: IAwaiter<T>
+    {
+        private Func<ETTask<T>> factory;
+        private ETTask<T> value;
+
+        public LazyPromise(Func<ETTask<T>> factory)
+        {
+            this.factory = factory;
+        }
+
+        private void Create()
+        {
+            var f = Interlocked.Exchange(ref factory, null);
+            if (f != null)
+            {
+                value = f();
+            }
+        }
+
+        public bool IsCompleted
+        {
+            get
+            {
+                Create();
+                return value.IsCompleted;
+            }
+        }
+
+        public AwaiterStatus Status
+        {
+            get
+            {
+                Create();
+                return value.Status;
+            }
+        }
+
+        public T GetResult()
+        {
+            Create();
+            return value.Result;
+        }
+
+        void IAwaiter.GetResult()
+        {
+            GetResult();
+        }
+
+        public void UnsafeOnCompleted(Action continuation)
+        {
+            Create();
+            value.GetAwaiter().UnsafeOnCompleted(continuation);
+        }
+
+        public void OnCompleted(Action continuation)
+        {
+            UnsafeOnCompleted(continuation);
+        }
+    }
+}

+ 11 - 0
Unity/Assets/Model/Base/Async/LazyPromise.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: bf276347e994763428d1a563259218f5
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 16 - 0
Unity/Assets/Model/Base/Async/MoveNextRunner.cs

@@ -0,0 +1,16 @@
+using System.Diagnostics;
+using System.Runtime.CompilerServices;
+
+namespace ETModel
+{
+    internal class MoveNextRunner<TStateMachine> where TStateMachine : IAsyncStateMachine
+    {
+        public TStateMachine StateMachine;
+
+        [DebuggerHidden]
+        public void Run()
+        {
+            StateMachine.MoveNext();
+        }
+    }
+}

+ 11 - 0
Unity/Assets/Model/Base/Async/MoveNextRunner.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 3832d83e9c3404c419b3760c2ebe3871
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 3 - 3
Unity/Assets/Model/Component/SceneChangeComponent.cs

@@ -19,13 +19,13 @@ namespace ETModel
 	public class SceneChangeComponent: Component
 	{
 		public AsyncOperation loadMapOperation;
-		public TaskCompletionSource<bool> tcs;
+		public ETTaskCompletionSource<bool> tcs;
 	    public float deltaTime;
 	    public int lastProgress = 0;
 
-		public Task<bool> ChangeSceneAsync(string sceneName)
+		public ETTask<bool> ChangeSceneAsync(string sceneName)
 		{
-			this.tcs = new TaskCompletionSource<bool>();
+			this.tcs = new ETTaskCompletionSource<bool>();
 			// 加载map
 			this.loadMapOperation = SceneManager.LoadSceneAsync(sceneName);
 			return this.tcs.Task;

+ 10 - 15
Unity/Assets/Model/Component/TimerComponent.cs

@@ -8,7 +8,7 @@ namespace ETModel
 	{
 		public long Id { get; set; }
 		public long Time { get; set; }
-		public TaskCompletionSource<bool> tcs;
+		public ETTaskCompletionSource<bool> tcs;
 	}
 
 	[ObjectSystem]
@@ -80,23 +80,18 @@ namespace ETModel
 					continue;
 				}
 				this.timers.Remove(timerId);
-				timer.tcs.SetResult(true);
+				timer.tcs.TrySetResult(true);
 			}
 		}
 
 		private void Remove(long id)
 		{
-			Timer timer;
-			if (!this.timers.TryGetValue(id, out timer))
-			{
-				return;
-			}
 			this.timers.Remove(id);
 		}
 
-		public Task WaitTillAsync(long tillTime, CancellationToken cancellationToken)
+		public ETTask WaitTillAsync(long tillTime, CancellationToken cancellationToken)
 		{
-			TaskCompletionSource<bool> tcs = new TaskCompletionSource<bool>();
+			ETTaskCompletionSource<bool> tcs = new ETTaskCompletionSource<bool>();
 			Timer timer = new Timer { Id = IdGenerater.GenerateId(), Time = tillTime, tcs = tcs };
 			this.timers[timer.Id] = timer;
 			this.timeId.Add(timer.Time, timer.Id);
@@ -108,9 +103,9 @@ namespace ETModel
 			return tcs.Task;
 		}
 
-		public Task WaitTillAsync(long tillTime)
+		public ETTask WaitTillAsync(long tillTime)
 		{
-			TaskCompletionSource<bool> tcs = new TaskCompletionSource<bool>();
+			ETTaskCompletionSource<bool> tcs = new ETTaskCompletionSource<bool>();
 			Timer timer = new Timer { Id = IdGenerater.GenerateId(), Time = tillTime, tcs = tcs };
 			this.timers[timer.Id] = timer;
 			this.timeId.Add(timer.Time, timer.Id);
@@ -121,9 +116,9 @@ namespace ETModel
 			return tcs.Task;
 		}
 
-		public Task WaitAsync(long time, CancellationToken cancellationToken)
+		public ETTask WaitAsync(long time, CancellationToken cancellationToken)
 		{
-			TaskCompletionSource<bool> tcs = new TaskCompletionSource<bool>();
+			ETTaskCompletionSource<bool> tcs = new ETTaskCompletionSource<bool>();
 			Timer timer = new Timer { Id = IdGenerater.GenerateId(), Time = TimeHelper.Now() + time, tcs = tcs };
 			this.timers[timer.Id] = timer;
 			this.timeId.Add(timer.Time, timer.Id);
@@ -135,9 +130,9 @@ namespace ETModel
 			return tcs.Task;
 		}
 
-		public Task WaitAsync(long time)
+		public ETTask WaitAsync(long time)
 		{
-			TaskCompletionSource<bool> tcs = new TaskCompletionSource<bool>();
+			ETTaskCompletionSource<bool> tcs = new ETTaskCompletionSource<bool>();
 			Timer timer = new Timer { Id = IdGenerater.GenerateId(), Time = TimeHelper.Now() + time, tcs = tcs };
 			this.timers[timer.Id] = timer;
 			this.timeId.Add(timer.Time, timer.Id);

+ 3 - 3
Unity/Assets/Model/Entity/UnityWebRequestAsync.cs

@@ -21,7 +21,7 @@ namespace ETModel
 
 		public bool isCancel;
 
-		public TaskCompletionSource<bool> tcs;
+		public ETTaskCompletionSource<bool> tcs;
 		
 		public override void Dispose()
 		{
@@ -82,9 +82,9 @@ namespace ETModel
 			this.tcs.SetResult(true);
 		}
 
-		public Task<bool> DownloadAsync(string url)
+		public ETTask<bool> DownloadAsync(string url)
 		{
-			this.tcs = new TaskCompletionSource<bool>();
+			this.tcs = new ETTaskCompletionSource<bool>();
 			
 			url = url.Replace(" ", "%20");
 			this.Request = UnityWebRequest.Get(url);

+ 9 - 9
Unity/Assets/Model/Entity/WWWAsync.cs

@@ -20,7 +20,7 @@ namespace ETModel
 
 		public bool isCancel;
 
-		public TaskCompletionSource<bool> tcs;
+		public ETTaskCompletionSource<bool> tcs;
 
 		public float Progress
 		{
@@ -70,36 +70,36 @@ namespace ETModel
 			t?.SetResult(true);
 		}
 
-		public Task<bool> LoadFromCacheOrDownload(string url, Hash128 hash)
+		public ETTask<bool> LoadFromCacheOrDownload(string url, Hash128 hash)
 		{
 			url = url.Replace(" ", "%20");
 			this.www = WWW.LoadFromCacheOrDownload(url, hash, 0);
-			this.tcs = new TaskCompletionSource<bool>();
+			this.tcs = new ETTaskCompletionSource<bool>();
 			return this.tcs.Task;
 		}
 
-		public Task<bool> LoadFromCacheOrDownload(string url, Hash128 hash, CancellationToken cancellationToken)
+		public ETTask<bool> LoadFromCacheOrDownload(string url, Hash128 hash, CancellationToken cancellationToken)
 		{
 			url = url.Replace(" ", "%20");
 			this.www = WWW.LoadFromCacheOrDownload(url, hash, 0);
-			this.tcs = new TaskCompletionSource<bool>();
+			this.tcs = new ETTaskCompletionSource<bool>();
 			cancellationToken.Register(() => { this.isCancel = true; });
 			return this.tcs.Task;
 		}
 
-		public Task<bool> DownloadAsync(string url)
+		public ETTask<bool> DownloadAsync(string url)
 		{
 			url = url.Replace(" ", "%20");
 			this.www = new WWW(url);
-			this.tcs = new TaskCompletionSource<bool>();
+			this.tcs = new ETTaskCompletionSource<bool>();
 			return this.tcs.Task;
 		}
 
-		public Task<bool> DownloadAsync(string url, CancellationToken cancellationToken)
+		public ETTask<bool> DownloadAsync(string url, CancellationToken cancellationToken)
 		{
 			url = url.Replace(" ", "%20");
 			this.www = new WWW(url);
-			this.tcs = new TaskCompletionSource<bool>();
+			this.tcs = new ETTaskCompletionSource<bool>();
 			cancellationToken.Register(() => { this.isCancel = true; });
 			return this.tcs.Task;
 		}

+ 4 - 0
Unity/Assets/Model/Init.cs

@@ -43,6 +43,10 @@ namespace ETModel
 
 				Game.Hotfix.GotoHotfix();
 
+				Log.Debug($"111111111111111111111111111111111111111");
+				await Game.Scene.GetComponent<TimerComponent>().WaitAsync(1000);
+				Log.Debug($"111111111111111111111111111111111111112");
+
 				Game.EventSystem.Run(EventIdType.TestHotfixSubscribMonoEvent, "TestHotfixSubscribMonoEvent");
 			}
 			catch (Exception e)

+ 4 - 4
Unity/Assets/Model/Module/AssetsBundle/AssetsBundleLoaderAsync.cs

@@ -17,7 +17,7 @@ namespace ETModel
 	{
 		private AssetBundleCreateRequest request;
 
-		private TaskCompletionSource<AssetBundle> tcs;
+		private ETTaskCompletionSource<AssetBundle> tcs;
 
 		public void Update()
 		{
@@ -26,7 +26,7 @@ namespace ETModel
 				return;
 			}
 
-			TaskCompletionSource<AssetBundle> t = tcs;
+			ETTaskCompletionSource<AssetBundle> t = tcs;
 			t.SetResult(this.request.assetBundle);
 		}
 
@@ -39,9 +39,9 @@ namespace ETModel
 			base.Dispose();
 		}
 
-		public Task<AssetBundle> LoadAsync(string path)
+		public ETTask<AssetBundle> LoadAsync(string path)
 		{
-			this.tcs = new TaskCompletionSource<AssetBundle>();
+			this.tcs = new ETTaskCompletionSource<AssetBundle>();
 			this.request = AssetBundle.LoadFromFileAsync(path);
 			return this.tcs.Task;
 		}

+ 4 - 4
Unity/Assets/Model/Module/AssetsBundle/AssetsLoaderAsync.cs

@@ -28,7 +28,7 @@ namespace ETModel
 
 		private AssetBundleRequest request;
 
-		private TaskCompletionSource<bool> tcs;
+		private ETTaskCompletionSource<bool> tcs;
 
 		public void Awake(AssetBundle ab)
 		{
@@ -42,7 +42,7 @@ namespace ETModel
 				return;
 			}
 
-			TaskCompletionSource<bool> t = tcs;
+			ETTaskCompletionSource<bool> t = tcs;
 			t.SetResult(true);
 		}
 
@@ -64,9 +64,9 @@ namespace ETModel
 			return this.request.allAssets;
 		}
 
-		private Task<bool> InnerLoadAllAssetsAsync()
+		private ETTask<bool> InnerLoadAllAssetsAsync()
 		{
-			this.tcs = new TaskCompletionSource<bool>();
+			this.tcs = new ETTaskCompletionSource<bool>();
 			this.request = assetBundle.LoadAllAssetsAsync();
 			return this.tcs.Task;
 		}

+ 5 - 5
Unity/Assets/Model/Module/Demo/MoveComponent.cs

@@ -39,7 +39,7 @@ namespace ETModel
 
 		public Vector3 Dest;
 
-		public TaskCompletionSource<bool> moveTcs;
+		public ETTaskCompletionSource<bool> moveTcs;
 
 		public Vector3 Speed
 		{
@@ -122,20 +122,20 @@ namespace ETModel
 			this.Dest = dest;
 		}
 
-		public Task<bool> MoveToAsync(Vector3 dest, float speedValue, CancellationToken cancellationToken)
+		public ETTask<bool> MoveToAsync(Vector3 dest, float speedValue, CancellationToken cancellationToken)
 		{
 			if ((dest - this.GetParent<Unit>().Position).magnitude < 0.1f)
 			{
 				this.IsArrived = true;
-				return Task.FromResult(false);
+				return ETTask.FromResult(false);
 			}
 
 			if ((dest - this.Dest).magnitude < 0.1f)
 			{
-				return Task.FromResult(false);
+				return ETTask.FromResult(false);
 			}
 			
-			this.moveTcs = new TaskCompletionSource<bool>();
+			this.moveTcs = new ETTaskCompletionSource<bool>();
 			this.IsArrived = false;
 			Vector3 spd = dest - this.GetParent<Unit>().Position;
 			spd = spd.normalized * speedValue;

+ 6 - 6
Unity/Assets/Model/Module/Message/Session.cs

@@ -183,10 +183,10 @@ namespace ETModel
 			action(response);
 		}
 
-		public Task<IResponse> Call(IRequest request)
+		public ETTask<IResponse> Call(IRequest request)
 		{
 			int rpcId = ++RpcId;
-			var tcs = new TaskCompletionSource<IResponse>();
+			var tcs = new ETTaskCompletionSource<IResponse>();
 
 			this.requestCallback[rpcId] = (response) =>
 			{
@@ -197,11 +197,11 @@ namespace ETModel
 						throw new RpcException(response.Error, response.Message);
 					}
 
-					tcs.SetResult(response);
+					tcs.TrySetResult(response);
 				}
 				catch (Exception e)
 				{
-					tcs.SetException(new Exception($"Rpc Error: {request.GetType().FullName}", e));
+					tcs.TrySetException(new Exception($"Rpc Error: {request.GetType().FullName}", e));
 				}
 			};
 
@@ -210,10 +210,10 @@ namespace ETModel
 			return tcs.Task;
 		}
 
-		public Task<IResponse> Call(IRequest request, CancellationToken cancellationToken)
+		public ETTask<IResponse> Call(IRequest request, CancellationToken cancellationToken)
 		{
 			int rpcId = ++RpcId;
-			var tcs = new TaskCompletionSource<IResponse>();
+			var tcs = new ETTaskCompletionSource<IResponse>();
 
 			this.requestCallback[rpcId] = (response) =>
 			{

+ 14 - 1
Unity/Unity.Model.csproj

@@ -9,7 +9,8 @@
     <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
     <ProductVersion>10.0.20506</ProductVersion>
     <SchemaVersion>2.0</SchemaVersion>
-    <RootNamespace></RootNamespace>
+    <RootNamespace>
+    </RootNamespace>
     <ProjectGuid>{B4BF9894-F5D9-41C4-13E3-3F26F7700E29}</ProjectGuid>
     <OutputType>Library</OutputType>
     <AppDesignerFolder>Properties</AppDesignerFolder>
@@ -54,6 +55,18 @@
     </Reference>
   </ItemGroup>
   <ItemGroup>
+    <Compile Include="Assets\Model\Base\Async\ETAsyncTaskMethodBuilder.cs" />
+    <Compile Include="Assets\Model\Base\Async\ETAsyncTaskVoidMethodBuilder.cs" />
+    <Compile Include="Assets\Model\Base\Async\AsyncMethodBuilderAttribute.cs" />
+    <Compile Include="Assets\Model\Base\Async\AsyncUnit.cs" />
+    <Compile Include="Assets\Model\Base\Async\CancellationTokenExtensions.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" />
+    <Compile Include="Assets\Model\Base\Async\ETTaskVoid.cs" />
+    <Compile Include="Assets\Model\Base\Async\IAwaiter.cs" />
+    <Compile Include="Assets\Model\Base\Async\LazyPromise.cs" />
+    <Compile Include="Assets\Model\Base\Async\MoveNextRunner.cs" />
     <Compile Include="Assets\Model\Base\DoubleMap.cs" />
     <Compile Include="Assets\Model\Base\Event\Env.cs" />
     <Compile Include="Assets\Model\Base\Event\EnvKey.cs" />