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

修改事件接口,不再使用Env传事件参数

tanghai 10 лет назад
Родитель
Сommit
8ab531a169

+ 1 - 0
CSharp/Game/Controller/Controller.csproj

@@ -39,6 +39,7 @@
   </ItemGroup>
   <ItemGroup>
     <Compile Include="AddressHelper.cs" />
+    <Compile Include="Event\SleepTimeoutEvent.cs" />
     <Compile Include="Event\BuffTimeoutEvent.cs" />
     <Compile Include="BehaviorTreeNode\Not.cs" />
     <Compile Include="BehaviorTreeNode\Selector.cs" />

+ 2 - 2
CSharp/Game/Controller/Event/BuffTimeoutEvent.cs

@@ -4,9 +4,9 @@ using MongoDB.Bson;
 namespace Controller
 {
 	[Event(EventType.BuffTimeout, ServerType.City)]
-	public class BuffTimeoutEvent: IEvent
+	public class BuffTimeoutEvent: AEvent<Env>
 	{
-		public void Run(Env env)
+		public override void Run(Env env)
 		{
 			Unit owner = World.Instance.GetComponent<UnitComponent>().Get(env.Get<ObjectId>(EnvKey.OwnerId));
 			if (owner == null)

+ 16 - 0
CSharp/Game/Controller/Event/SleepTimeoutEvent.cs

@@ -0,0 +1,16 @@
+using System.Threading.Tasks;
+using Model;
+
+namespace Controller
+{
+	[Event(EventType.SleepTimeout, ServerType.City)]
+	public class SleepTimeoutEvent_RunTcs : AEvent<Env>
+	{
+		public override void Run(Env env)
+		{
+			TaskCompletionSource<bool> tcs =
+					env.Get<TaskCompletionSource<bool>>(EnvKey.SleepTimeout_TaskCompletionSource);
+			tcs.SetResult(true);
+		}
+	}
+}

+ 4 - 4
CSharp/Game/Model/Component/BuffComponent.cs

@@ -62,13 +62,13 @@ namespace Model
 			env[EnvKey.Owner] = this.Owner;
 			env[EnvKey.Buff] = buff;
 
-			World.Instance.GetComponent<EventComponent<EventAttribute>>().Run(EventType.BeforeAddBuff, env);
+			World.Instance.GetComponent<EventComponent<EventAttribute>>().RunAsync(EventType.BeforeAddBuff, env);
 
 			this.buffs.Add(buff);
 			this.idBuff.Add(buff.Id, buff);
 			this.typeBuff.Add(buff.Config.Type, buff);
 
-			World.Instance.GetComponent<EventComponent<EventAttribute>>().Run(EventType.AfterAddBuff, env);
+			World.Instance.GetComponent<EventComponent<EventAttribute>>().RunAsync(EventType.AfterAddBuff, env);
 		}
 
 		public Buff GetById(ObjectId id)
@@ -103,13 +103,13 @@ namespace Model
 			env[EnvKey.Buff] = buff;
 
 			World.Instance.GetComponent<EventComponent<EventAttribute>>()
-					.Run(EventType.BeforeRemoveBuff, env);
+					.RunAsync(EventType.BeforeRemoveBuff, env);
 
 			this.buffs.Remove(buff);
 			this.idBuff.Remove(buff.Id);
 			this.typeBuff.Remove(buff.Config.Type, buff);
 
-			World.Instance.GetComponent<EventComponent<EventAttribute>>().Run(EventType.AfterRemoveBuff, env);
+			World.Instance.GetComponent<EventComponent<EventAttribute>>().RunAsync(EventType.AfterRemoveBuff, env);
 			buff.Dispose();
 		}
 

+ 144 - 41
CSharp/Game/Model/Component/EventComponent.cs

@@ -3,19 +3,18 @@ using System.Collections.Generic;
 using System.Reflection;
 using System.Threading.Tasks;
 using Common.Base;
+using Common.Logger;
 
 namespace Model
 {
 	public class EventComponent<AttributeType>: Component<World>, IAssemblyLoader
 			where AttributeType : AEventAttribute
 	{
-		private Dictionary<EventType, List<IEvent>> eventSyncs;
-		private Dictionary<EventType, List<IEventAsync>> eventAsyncs;
+		private Dictionary<EventType, List<object>> allEvents;
 
 		public void Load(Assembly assembly)
 		{
-			this.eventSyncs = new Dictionary<EventType, List<IEvent>>();
-			this.eventAsyncs = new Dictionary<EventType, List<IEventAsync>>();
+			this.allEvents = new Dictionary<EventType, List<object>>();
 
 			ServerType serverType = World.Instance.Options.ServerType;
 
@@ -35,76 +34,180 @@ namespace Model
 				}
 
 				object obj = Activator.CreateInstance(t);
-				IEvent iEvent = obj as IEvent;
-				if (iEvent != null)
+				if (obj == null)
 				{
-					if (!this.eventSyncs.ContainsKey(aEventAttribute.Type))
+					throw new Exception(string.Format("event not inherit IEvent or IEventAsync interface: {0}",
+							obj.GetType().FullName));
+				}
+				if (!this.allEvents.ContainsKey(aEventAttribute.Type))
+				{
+					this.allEvents.Add(aEventAttribute.Type, new List<object>());
+				}
+				this.allEvents[aEventAttribute.Type].Add(obj);
+			}
+		}
+
+		public async Task RunAsync(EventType type)
+		{
+			List<object> iEvents = null;
+			if (!this.allEvents.TryGetValue(type, out iEvents))
+			{
+				return;
+			}
+
+			foreach (object obj in iEvents)
+			{
+				try
+				{
+					AEvent iEvent = obj as AEvent;
+					if (iEvent == null)
 					{
-						this.eventSyncs.Add(aEventAttribute.Type, new List<IEvent>());
+						throw new GameException(string.Format("event type: {0} is not IEvent", type));
 					}
-					this.eventSyncs[aEventAttribute.Type].Add(iEvent);
-					continue;
+					iEvent.Run();
+					await iEvent.RunAsync();
+				}
+				catch (Exception err)
+				{
+					Log.Debug(err.ToString());
 				}
+			}
+		}
 
-				IEventAsync iEventAsync = obj as IEventAsync;
-				// ReSharper disable once InvertIf
-				if (iEventAsync != null)
+		public async Task RunAsync<A>(EventType type, A a)
+		{
+			List<object> iEvents = null;
+			if (!this.allEvents.TryGetValue(type, out iEvents))
+			{
+				return;
+			}
+
+			foreach (object obj in iEvents)
+			{
+				try
 				{
-					if (!this.eventAsyncs.ContainsKey(aEventAttribute.Type))
+					AEvent<A> iEvent = obj as AEvent<A>;
+					if (iEvent == null)
 					{
-						this.eventAsyncs.Add(aEventAttribute.Type, new List<IEventAsync>());
+						throw new GameException(string.Format("event type: {0} is not IEvent<{1}>", type, typeof(A).Name));
 					}
-					this.eventAsyncs[aEventAttribute.Type].Add(iEventAsync);
-					continue;
+					iEvent.Run(a);
+					await iEvent.RunAsync(a);
+				}
+				catch (Exception err)
+				{
+					Log.Debug(err.ToString());
 				}
-
-				throw new Exception(string.Format("event not inherit IEvent or IEventAsync interface: {0}",
-						obj.GetType().FullName));
 			}
 		}
 
-		public void Run(EventType type, Env env)
+		public async Task RunAsync<A, B>(EventType type, A a, B b)
 		{
-			List<IEvent> iEventSyncs = null;
-			if (!this.eventSyncs.TryGetValue(type, out iEventSyncs))
+			List<object> iEvents = null;
+			if (!this.allEvents.TryGetValue(type, out iEvents))
 			{
-				throw new Exception(string.Format("no event handler, AttributeType: {0} type: {1}",
-						typeof (AttributeType).Name, type));
+				return;
 			}
 
-			foreach (IEvent iEventSync in iEventSyncs)
+			foreach (object obj in iEvents)
 			{
-				iEventSync.Run(env);
+				try
+				{
+					AEvent<A, B> iEvent = obj as AEvent<A, B>;
+					if (iEvent == null)
+					{
+						throw new GameException(string.Format("event type: {0} is not IEvent<{1}, {2}>", type, typeof(A).Name, typeof(B).Name));
+					}
+					iEvent.Run(a, b);
+					await iEvent.RunAsync(a, b);
+				}
+				catch (Exception err)
+				{
+					Log.Debug(err.ToString());
+				}
 			}
 		}
 
-		public async Task RunAsync(EventType type, Env env)
+		public async Task RunAsync<A, B, C>(EventType type, A a, B b, C c)
 		{
-			List<IEvent> iEventSyncs = null;
-			this.eventSyncs.TryGetValue(type, out iEventSyncs);
+			List<object> iEvents = null;
+			if (!this.allEvents.TryGetValue(type, out iEvents))
+			{
+				return;
+			}
 
-			List<IEventAsync> iEventAsyncs = null;
-			this.eventAsyncs.TryGetValue(type, out iEventAsyncs);
+			foreach (object obj in iEvents)
+			{
+				try
+				{
+					AEvent<A, B, C> iEvent = obj as AEvent<A, B, C>;
+					if (iEvent == null)
+					{
+						throw new GameException(string.Format("event type: {0} is not IEvent<{1}, {2}, {3}>", type,
+							typeof(A).Name, typeof(B).Name, typeof(C).Name));
+					}
+					iEvent.Run(a, b, c);
+					await iEvent.RunAsync(a, b, c);
+				}
+				catch (Exception err)
+				{
+					Log.Debug(err.ToString());
+				}
+			}
+		}
 
-			if (iEventSyncs == null && iEventAsyncs == null)
+		public async Task RunAsync<A, B, C, D>(EventType type, A a, B b, C c, D d)
+		{
+			List<object> iEvents = null;
+			if (!this.allEvents.TryGetValue(type, out iEvents))
 			{
-				throw new Exception(string.Format("no event handler, AttributeType: {0} type: {1}",
-						typeof (AttributeType).Name, type));
+				return;
 			}
 
-			if (iEventSyncs != null)
+			foreach (object obj in iEvents)
 			{
-				foreach (IEvent iEventSync in iEventSyncs)
+				try
 				{
-					iEventSync.Run(env);
+					AEvent<A, B, C, D> iEvent = obj as AEvent<A, B, C, D>;
+					if (iEvent == null)
+					{
+						throw new GameException(string.Format("event type: {0} is not IEvent<{1}, {2}, {3}, {4}>", type,
+							typeof(A).Name, typeof(B).Name, typeof(C).Name, typeof(D).Name));
+					}
+					iEvent.Run(a, b, c, d);
+					await iEvent.RunAsync(a, b, c, d);
 				}
+				catch (Exception err)
+				{
+					Log.Debug(err.ToString());
+				}
+			}
+		}
+
+		public async Task RunAsync<A, B, C, D, E>(EventType type, A a, B b, C c, D d, E e)
+		{
+			List<object> iEvents = null;
+			if (!this.allEvents.TryGetValue(type, out iEvents))
+			{
+				return;
 			}
 
-			if (iEventAsyncs != null)
+			foreach (object obj in iEvents)
 			{
-				foreach (IEventAsync iEventAsync in iEventAsyncs)
+				try
+				{
+					AEvent<A, B, C, D, E> iEvent = obj as AEvent<A, B, C, D, E>;
+					if (iEvent == null)
+					{
+						throw new GameException(string.Format("event type: {0} is not IEvent<{1}, {2}, {3}, {4}, {5}>", type,
+							typeof(A).Name, typeof(B).Name, typeof(C).Name, typeof(D).Name, typeof(E).Name));
+					}
+					iEvent.Run(a, b, c, d, e);
+					await iEvent.RunAsync(a, b, c, d, e);
+				}
+				catch (Exception err)
 				{
-					await iEventAsync.RunAsync(env);
+					Log.Debug(err.ToString());
 				}
 			}
 		}

+ 4 - 9
CSharp/Game/Model/Component/GateNetworkComponent.cs

@@ -68,20 +68,15 @@ namespace Model
 			while (true)
 			{
 				byte[] messageBytes = await channel.RecvAsync();
-				Env env = new Env();
-				env[EnvKey.Channel] = channel;
-				env[EnvKey.MessageBytes] = messageBytes;
 				Opcode opcode = (Opcode)BitConverter.ToUInt16(messageBytes, 0);
-				env[EnvKey.Opcode] = opcode;
-				if (!MessageTypeHelper.IsClientMessage(opcode))
+				if (!OpcodeHelper.IsClientMessage(opcode))
 				{
 					continue;
 				}
 
-#pragma warning disable 4014
-				World.Instance.GetComponent<EventComponent<EventAttribute>>()
-						.RunAsync(EventType.GateRecvClientMessage, env);
-#pragma warning restore 4014
+				ObjectId unitId = channel.GetComponent<ChannelUnitInfoComponent>().UnitId;
+				Actor actor = World.Instance.GetComponent<ActorComponent>().Get(unitId);
+				actor.Add(messageBytes);
 			}
 		}
 

+ 15 - 17
CSharp/Game/Model/Component/NetworkComponent.cs

@@ -109,7 +109,7 @@ namespace Model
 				}
 
 				// 如果是server message(发给client的消息),说明这是gate server,需要根据unitid查到channel,进行发送
-				if (MessageTypeHelper.IsServerMessage(opcode))
+				if (OpcodeHelper.IsServerMessage(opcode))
 				{
 					byte[] idBuffer = new byte[12];
 					Array.Copy(messageBytes, 2, idBuffer, 0, 12);
@@ -176,23 +176,21 @@ namespace Model
 			var tcs = new TaskCompletionSource<T>();
 			this.requestCallback[this.requestId] = (messageBytes, status) =>
 			{
-				if (status == RpcResponseStatus.Timeout)
+				switch (status)
 				{
-					tcs.SetException(new Exception(
-						string.Format("rpc timeout {0} {1}", opcode, MongoHelper.ToJson(request))));
-					return;
-				}
-				if (status == RpcResponseStatus.Exception)
-				{
-					BinaryFormatter formatter = new BinaryFormatter(null, new StreamingContext(StreamingContextStates.All));
-					Exception exception;
-					using (MemoryStream stream = new MemoryStream(messageBytes))
-					{
-						stream.Seek(6, SeekOrigin.Begin);
-						exception = (Exception)formatter.Deserialize(stream);
-					}
-					tcs.SetException(exception);
-					return;
+					case RpcResponseStatus.Timeout:
+						tcs.SetException(new Exception(
+								string.Format("rpc timeout {0} {1}", opcode, MongoHelper.ToJson(request))));
+						return;
+					case RpcResponseStatus.Exception:
+						BinaryFormatter formatter = new BinaryFormatter(null, new StreamingContext(StreamingContextStates.All));
+						Exception exception;
+						using (MemoryStream stream = new MemoryStream(messageBytes, 6, messageBytes.Length - 6))
+						{
+							exception = (Exception)formatter.Deserialize(stream);
+						}
+						tcs.SetException(exception);
+						return;
 				}
 
 				// RpcResponseStatus.Succee

+ 22 - 15
CSharp/Game/Model/Component/TimerComponent.cs

@@ -1,4 +1,6 @@
 using System.Collections.Generic;
+using System.Threading;
+using System.Threading.Tasks;
 using Common.Base;
 using Common.Helper;
 using MongoDB.Bson;
@@ -21,9 +23,7 @@ namespace Model
 		/// key: time, value: timer id
 		/// </summary>
 		private readonly MultiMap<long, ObjectId> timeId = new MultiMap<long, ObjectId>();
-
-		private readonly Queue<long> timeoutTimer = new Queue<long>();
-
+		
 		public ObjectId Add(long time, EventType callbackEvent, Env env)
 		{
 			Timer timer = new Timer
@@ -48,31 +48,38 @@ namespace Model
 			this.timeId.Remove(timer.Time, timer.Id);
 		}
 
+		public Task<bool> Sleep(int time)
+		{
+			TaskCompletionSource<bool> tcs = new TaskCompletionSource<bool>();
+			Env env = new Env();
+			env[EnvKey.SleepTimeout_TaskCompletionSource] = tcs;
+			this.Add(TimeHelper.Now() + time, EventType.SleepTimeout, env);
+			return tcs.Task;
+		}
+
 		public void Update()
 		{
 			long timeNow = TimeHelper.Now();
-			foreach (long time in this.timeId.Keys)
+
+			while (true)
 			{
-				if (time > timeNow)
+				KeyValuePair<long, List<ObjectId>> first = this.timeId.First;
+				if (first.Key > timeNow)
 				{
-					break;
+					return;
 				}
-				this.timeoutTimer.Enqueue(time);
-			}
 
-			while (this.timeoutTimer.Count > 0)
-			{
-				long key = this.timeoutTimer.Dequeue();
-				List<ObjectId> timeOutId = this.timeId[key];
-				foreach (ObjectId id in timeOutId)
+				List<ObjectId> timeoutId = first.Value;
+				this.timeId.Remove(first.Key);
+				foreach (ObjectId id in timeoutId)
 				{
 					Timer timer;
 					if (!this.timers.TryGetValue(id, out timer))
 					{
 						continue;
 					}
-					this.Remove(id);
-					World.Instance.GetComponent<EventComponent<EventAttribute>>().Run(timer.CallbackEvent, timer.Env);
+					this.timers.Remove(id);
+					World.Instance.GetComponent<EventComponent<EventAttribute>>().RunAsync(timer.CallbackEvent, timer.Env);
 				}
 			}
 		}

+ 2 - 0
CSharp/Game/Model/EnvKey.cs

@@ -12,5 +12,7 @@
 		public const string Opcode = "Opcode";
 		public const string MessageUnitId = "MessageUnitId";
 		public const string RpcRequestId = "RpcRequestId";
+
+		public const string SleepTimeout_TaskCompletionSource = "SleepTimeout_TaskCompletionSource";
 	}
 }

+ 1 - 4
CSharp/Game/Model/EventType.cs

@@ -7,9 +7,6 @@
 		BeforeRemoveBuff = 2,
 		AfterRemoveBuff = 3,
 		BuffTimeout = 4,
-		LogicRecvClientMessage = 5,
-		LogicRecvRequestMessage = 6,
-		GateRecvClientMessage = 7,
-		GateRecvServerMessage = 8,
+		SleepTimeout = 9,
 	}
 }

+ 66 - 3
CSharp/Game/Model/IEvent.cs

@@ -1,7 +1,70 @@
-namespace Model
+using System.Threading.Tasks;
+
+namespace Model
 {
-	public interface IEvent
+	public abstract class AEvent
 	{
-		void Run(Env env);
+		public virtual void Run()
+		{
+		}
+
+		public async virtual Task RunAsync()
+		{
+		}
+	}
+
+	public abstract class AEvent<A>
+	{
+		public virtual void Run(A a)
+		{
+		}
+
+		public async virtual Task RunAsync(A a)
+		{	
+		}
+	}
+
+	public abstract class AEvent<A, B>
+	{
+		public virtual void Run(A a, B b)
+		{
+		}
+
+		public async virtual Task RunAsync(A a, B b)
+		{
+		}
+	}
+
+	public abstract class AEvent<A, B, C>
+	{
+		public virtual void Run(A a, B b, C c)
+		{
+		}
+
+		public async virtual Task RunAsync(A a, B b, C c)
+		{
+		}
+	}
+
+	public abstract class AEvent<A, B, C, D>
+	{
+		public virtual void Run(A a, B b, C c, D d)
+		{
+		}
+
+		public async virtual Task RunAsync(A a, B b, C c, D d)
+		{
+		}
+	}
+
+	public abstract class AEvent<A, B, C, D, E>
+	{
+		public virtual void Run(A a, B b, C c, D d, E e)
+		{
+		}
+
+		public async virtual Task RunAsync(A a, B b, C c, D d, E e)
+		{
+		}
 	}
 }

+ 0 - 9
CSharp/Game/Model/IEventAsync.cs

@@ -1,9 +0,0 @@
-using System.Threading.Tasks;
-
-namespace Model
-{
-	public interface IEventAsync
-	{
-		Task RunAsync(Env env);
-	}
-}

+ 1 - 1
CSharp/Game/Model/Model.csproj

@@ -84,7 +84,6 @@
     <Compile Include="ICategory.cs" />
     <Compile Include="IConfigLoader.cs" />
     <Compile Include="IRegister.cs" />
-    <Compile Include="IEventAsync.cs" />
     <Compile Include="IEvent.cs" />
     <Compile Include="IFactory.cs" />
     <Compile Include="IStart.cs" />
@@ -93,6 +92,7 @@
     <Compile Include="NodeType.cs" />
     <Compile Include="Opcode.cs" />
     <Compile Include="NumDefine.cs" />
+    <Compile Include="OpcodeHelper.cs" />
     <Compile Include="Options.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
     <Compile Include="ServerType.cs" />

+ 0 - 39
CSharp/Game/Model/Opcode.cs

@@ -6,43 +6,4 @@
 		RpcResponse = 30000,
 		RpcException = 30001,
 	}
-
-	public static class MessageTypeHelper
-	{
-		public static bool IsClientMessage(Opcode opcode)
-		{
-			if ((ushort)opcode > 0 && (ushort)opcode < 10000)
-			{
-				return true;
-			}
-			return false;
-		}
-
-		public static bool IsServerMessage(Opcode opcode)
-		{
-			if ((ushort)opcode > 10000 && (ushort)opcode < 20000)
-			{
-				return true;
-			}
-			return false;
-		}
-
-		public static bool IsRpcRequestMessage(Opcode opcode)
-		{
-			if ((ushort)opcode > 20000 && (ushort)opcode < 30000)
-			{
-				return true;
-			}
-			return false;
-		}
-
-		public static bool IsRpcResponseMessage(Opcode opcode)
-		{
-			if ((ushort)opcode > 30000 && (ushort)opcode < 40000)
-			{
-				return true;
-			}
-			return false;
-		}
-	}
 }

+ 41 - 0
CSharp/Game/Model/OpcodeHelper.cs

@@ -0,0 +1,41 @@
+namespace Model
+{
+	public static class OpcodeHelper
+	{
+		public static bool IsClientMessage(Opcode opcode)
+		{
+			if ((ushort)opcode > 0 && (ushort)opcode < 10000)
+			{
+				return true;
+			}
+			return false;
+		}
+
+		public static bool IsServerMessage(Opcode opcode)
+		{
+			if ((ushort)opcode > 10000 && (ushort)opcode < 20000)
+			{
+				return true;
+			}
+			return false;
+		}
+
+		public static bool IsRpcRequestMessage(Opcode opcode)
+		{
+			if ((ushort)opcode > 20000 && (ushort)opcode < 30000)
+			{
+				return true;
+			}
+			return false;
+		}
+
+		public static bool IsRpcResponseMessage(Opcode opcode)
+		{
+			if ((ushort)opcode > 30000 && (ushort)opcode < 40000)
+			{
+				return true;
+			}
+			return false;
+		}
+	}
+}

+ 9 - 0
CSharp/Platform/Common/Base/MultiMap.cs

@@ -1,4 +1,5 @@
 using System.Collections.Generic;
+using System.Linq;
 
 namespace Common.Base
 {
@@ -26,6 +27,14 @@ namespace Common.Base
 			this.dictionary[t] = list;
 		}
 
+		public KeyValuePair<T, List<K>> First
+		{
+			get
+			{
+				return dictionary.First();
+			}
+		}
+
 		public bool Remove(T t, K k)
 		{
 			List<K> list;

+ 21 - 14
CSharp/Platform/Common/Base/TimerManager.cs

@@ -1,5 +1,6 @@
 using System;
 using System.Collections.Generic;
+using System.Threading;
 using System.Threading.Tasks;
 using Common.Helper;
 using MongoDB.Bson;
@@ -20,7 +21,7 @@ namespace Common.Base
 		/// <summary>
 		/// key: time, value: timer id
 		/// </summary>
-		private readonly MultiMap<long, ObjectId> timeGuid = new MultiMap<long, ObjectId>();
+		private readonly MultiMap<long, ObjectId> timeId = new MultiMap<long, ObjectId>();
 
 		private readonly Queue<long> timeoutTimer = new Queue<long>();
 
@@ -28,7 +29,7 @@ namespace Common.Base
 		{
 			Timer timer = new Timer { Id = ObjectId.GenerateNewId(), Time = time, Action = action };
 			this.timers[timer.Id] = timer;
-			this.timeGuid.Add(timer.Time, timer.Id);
+			this.timeId.Add(timer.Time, timer.Id);
 			return timer.Id;
 		}
 
@@ -40,7 +41,7 @@ namespace Common.Base
 				return;
 			}
 			this.timers.Remove(timer.Id);
-			this.timeGuid.Remove(timer.Time, timer.Id);
+			this.timeId.Remove(timer.Time, timer.Id);
 		}
 
 		public Task<bool> Sleep(int time)
@@ -50,30 +51,36 @@ namespace Common.Base
 			return tcs.Task;
 		}
 
+		public Task<bool> Sleep(int time, CancellationToken token)
+		{
+			TaskCompletionSource<bool> tcs = new TaskCompletionSource<bool>();
+			ObjectId id = this.Add(TimeHelper.Now() + time, () => { tcs.SetResult(true); });
+			token.Register(() => { this.Remove(id); });
+			return tcs.Task;
+		}
+
 		public void Refresh()
 		{
 			long timeNow = TimeHelper.Now();
-			foreach (long time in this.timeGuid.Keys)
+
+			while (true)
 			{
-				if (time > timeNow)
+				KeyValuePair<long, List<ObjectId>> first = this.timeId.First;
+				if (first.Key > timeNow)
 				{
-					break;
+					return;
 				}
-				this.timeoutTimer.Enqueue(time);
-			}
 
-			while (this.timeoutTimer.Count > 0)
-			{
-				long key = this.timeoutTimer.Dequeue();
-				ObjectId[] timeoutIds = this.timeGuid.GetAll(key);
-				foreach (ObjectId id in timeoutIds)
+				List<ObjectId> timeoutId = first.Value;
+				this.timeId.Remove(first.Key);
+				foreach (ObjectId id in timeoutId)
 				{
 					Timer timer;
 					if (!this.timers.TryGetValue(id, out timer))
 					{
 						continue;
 					}
-					this.Remove(id);
+					this.timers.Remove(id);
 					timer.Action();
 				}
 			}