From 5caff2dbda1e159983ab80c4670a2762e68437ea Mon Sep 17 00:00:00 2001 From: sin365 <353374337@qq.com> Date: Fri, 27 Dec 2024 14:00:52 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9C=8D=E5=8A=A1=E7=AB=AF=E8=B7=9F=E9=9A=8F?= =?UTF-8?q?=E6=96=B0=E7=94=A8=E6=88=B7=E6=A7=BD=E4=BD=8D=20=E6=9B=B4?= =?UTF-8?q?=E6=94=B9=E7=AE=A1=E7=90=86=20=EF=BC=8C=E4=BB=A5=E5=8F=8A?= =?UTF-8?q?=E5=AF=B9=E8=B1=A1=E6=B1=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Common/ObjectPoolAuto.cs | 401 ++++++++++++++++++ AxibugEmuOnline.Server/Event/EventSystem.cs | 12 +- AxibugEmuOnline.Server/Manager/AppSrv.cs | 2 +- .../Manager/GameShareManager.cs | 2 - AxibugEmuOnline.Server/Manager/LogManager.cs | 13 +- AxibugEmuOnline.Server/Manager/RoomManager.cs | 102 +++-- AxibugEmuOnline.Server/NetWork/NetMsg.cs | 12 +- AxibugEmuOnline.Server/Program.cs | 6 +- 8 files changed, 515 insertions(+), 35 deletions(-) create mode 100644 AxibugEmuOnline.Server/Common/ObjectPoolAuto.cs diff --git a/AxibugEmuOnline.Server/Common/ObjectPoolAuto.cs b/AxibugEmuOnline.Server/Common/ObjectPoolAuto.cs new file mode 100644 index 0000000..f5b4716 --- /dev/null +++ b/AxibugEmuOnline.Server/Common/ObjectPoolAuto.cs @@ -0,0 +1,401 @@ +using System.Reflection; +using System.Text; + +namespace AxibugEmuOnline.Server +{ + public static class ObjectPoolAuto + { + /************************************************************************************************************************/ + + /// + /// 获取或者创建一个新的 + /// + /// Remember to 需要回收参见这个 + public static T Acquire() + where T : class, new() + => ObjectPool.Acquire(); + + /// + /// 获取或者创建一个新的 + /// + /// Remember to 需要回收参见这个 + public static void Acquire(out T item) + where T : class, new() + => item = ObjectPool.Acquire(); + /************************************************************************************************************************/ + + /// + /// 回收对象 + /// + public static void Release(T item) + where T : class, new() + => ObjectPool.Release(item); + + /// + /// 回收对象 + /// + public static void Release(ref T item) where T : class, new() + { + if (item != null) + { + ObjectPool.Release(item); + item = null; + } + } + + /************************************************************************************************************************/ + public const string + NotClearError = " They must be cleared before being released to the pool and not modified after that."; + + /************************************************************************************************************************/ + + /// + /// 获取或创建List + /// + /// Remember to 回收参见此方法 + public static List AcquireList() + { + var list = ObjectPool>.Acquire(); + AppSrv.g_Log.Assert(list.Count == 0, "A pooled list is not empty." + NotClearError); + return list; + } + + /// + /// 回收List + /// + public static void Release(List list) + { + list.Clear(); + ObjectPool>.Release(list); + } + + /************************************************************************************************************************/ + + /// + /// 获取或创建Queue + /// + /// Remember to 回收参见此方法 + public static Queue AcquireQueue() + { + var queue = ObjectPool>.Acquire(); + AppSrv.g_Log.Assert(queue.Count == 0, "A pooled list is not empty." + NotClearError); + return queue; + } + + /// + /// 回收Queue + /// + public static void Release(Queue list) + { + list.Clear(); + ObjectPool>.Release(list); + } + + + /************************************************************************************************************************/ + + /// + /// 获取或创建HashSet + /// + public static HashSet AcquireSet() + { + var set = ObjectPool>.Acquire(); + AppSrv.g_Log.Assert(set.Count == 0, "A pooled set is not empty." + NotClearError); + return set; + } + + /// + /// 释放HashSet + /// + public static void Release(HashSet set) + { + set.Clear(); + ObjectPool>.Release(set); + } + + /************************************************************************************************************************/ + + /// + /// 获取一个字符串StringBuilder + /// + /// Remember to 回收参见这个 + public static StringBuilder AcquireStringBuilder() + { + var builder = ObjectPool.Acquire(); + AppSrv.g_Log.Assert(builder.Length == 0, $"A pooled {nameof(StringBuilder)} is not empty." + NotClearError); + return builder; + } + + /// + /// 回收 StringBuilder + /// + public static void Release(StringBuilder builder) + { + builder.Length = 0; + ObjectPool.Release(builder); + } + + /// + /// 回收 StringBuilder + /// + public static string ReleaseToString(this StringBuilder builder) + { + var result = builder.ToString(); + Release(builder); + return result; + } + + /************************************************************************************************************************/ + + private static class Cache + { + public static readonly Dictionary, T>> + Results = new Dictionary, T>>(); + } + + /// + /// 此方法主要用于频繁绘制缓存,比如说GUI绘制 + /// + public static T GetCachedResult(Func function) + { + var method = function.Method; + if (!Cache.Results.TryGetValue(method, out var result)) + { + + result = new KeyValuePair, T>(function, function()); + Cache.Results.Add(method, result); + } + else if (result.Key != function) + { + AppSrv.g_Log.Warning( + $"{nameof(GetCachedResult)}<{typeof(T).Name}>" + + $" was previously called on {method.Name} with a different target." + + " This likely means that a new delegate is being passed into every call" + + " so it can't actually return the same cached object."); + } + + return result.Value; + } + + /************************************************************************************************************************/ + + public static class Disposable + { + /************************************************************************************************************************/ + + /// + /// Calls to get a spare if + /// + public static IDisposable Acquire(out T item) + where T : class, new() + => ObjectPool.Disposable.Acquire(out item); + + /************************************************************************************************************************/ + + /// + /// Calls to get a spare if + /// + public static IDisposable AcquireList(out List list) + { + var disposable = ObjectPool>.Disposable.Acquire(out list, onRelease: (l) => l.Clear()); + AppSrv.g_Log.Assert(list.Count == 0, "A pooled list is not empty." + NotClearError); + return disposable; + } + + /************************************************************************************************************************/ + + /// + /// Calls to get a spare if + /// + public static IDisposable AcquireSet(out HashSet set) + { + var disposable = ObjectPool>.Disposable.Acquire(out set, onRelease: (s) => s.Clear()); + AppSrv.g_Log.Assert(set.Count == 0, "A pooled set is not empty." + NotClearError); + return disposable; + } + + /************************************************************************************************************************/ + } + /************************************************************************************************************************/ + } + + public static class ObjectPool where T : class, new() + { + /************************************************************************************************************************/ + + private static readonly List + Items = new List(); + + /************************************************************************************************************************/ + + /// The number of spare items currently in the pool. + public static int Count + { + get => Items.Count; + set + { + var count = Items.Count; + if (count < value) + { + if (Items.Capacity < value) + Items.Capacity = NextPowerOfTwo(value); + + do + { + Items.Add(new T()); + count++; + } + while (count < value); + + } + else if (count > value) + { + Items.RemoveRange(value, count - value); + } + } + } + + public static int NextPowerOfTwo(int value) + { + if (value <= 0) + { + throw new ArgumentException("Value must be greater than zero."); + } + + int powerOfTwo = 1; + while (powerOfTwo < value) + { + powerOfTwo <<= 1; // equivalent to multiplying by 2 + } + + return powerOfTwo; + } + + /************************************************************************************************************************/ + + /// + /// If the is less than the specified value, this method increases it to that value by + /// creating new objects. + /// + public static void SetMinCount(int count) + { + if (Count < count) + Count = count; + } + + /************************************************************************************************************************/ + + /// The of the internal list of spare items. + public static int Capacity + { + get => Items.Capacity; + set + { + if (Items.Count > value) + Items.RemoveRange(value, Items.Count - value); + Items.Capacity = value; + } + } + + /************************************************************************************************************************/ + + /// Returns a spare item if there are any, or creates a new one. + /// Remember to it when you are done. + public static T Acquire() + { + var count = Items.Count; + if (count == 0) + { + return new T(); + } + else + { + count--; + var item = Items[count]; + Items.RemoveAt(count); + + return item; + } + } + + /************************************************************************************************************************/ + + /// Adds the `item` to the list of spares so it can be reused. + public static void Release(T item) + { + Items.Add(item); + + } + + /************************************************************************************************************************/ + + /// Returns a description of the state of this pool. + public static string GetDetails() + { + return + $"{typeof(T).Name}" + + $" ({nameof(Count)} = {Items.Count}" + + $", {nameof(Capacity)} = {Items.Capacity}" + + ")"; + } + + /************************************************************************************************************************/ + + /// + /// An system to allow pooled objects to be acquired and released within using + /// statements instead of needing to manually release everything. + /// + public sealed class Disposable : IDisposable + { + /************************************************************************************************************************/ + + private static readonly List LazyStack = new List(); + + private static int _ActiveDisposables; + + private T _Item; + private Action _OnRelease; + + /************************************************************************************************************************/ + + private Disposable() { } + + /// + /// Calls to set the `item` and returns an + /// that will call on the `item` when disposed. + /// + public static IDisposable Acquire(out T item, Action onRelease = null) + { + Disposable disposable; + + if (LazyStack.Count <= _ActiveDisposables) + { + LazyStack.Add(disposable = new Disposable()); + } + else + { + disposable = LazyStack[_ActiveDisposables]; + } + + _ActiveDisposables++; + + disposable._Item = item = ObjectPool.Acquire(); + disposable._OnRelease = onRelease; + return disposable; + } + + /************************************************************************************************************************/ + + void IDisposable.Dispose() + { + _OnRelease?.Invoke(_Item); + Release(_Item); + _ActiveDisposables--; + } + + /************************************************************************************************************************/ + } + } +} + + diff --git a/AxibugEmuOnline.Server/Event/EventSystem.cs b/AxibugEmuOnline.Server/Event/EventSystem.cs index b15194d..e64a6e1 100644 --- a/AxibugEmuOnline.Server/Event/EventSystem.cs +++ b/AxibugEmuOnline.Server/Event/EventSystem.cs @@ -50,7 +50,10 @@ namespace AxibugEmuOnline.Server.Event } else { - eventDic.Add(evt, new List() { callback }); + //eventDic.Add(evt, new List() { callback }); + List delList = ObjectPoolAuto.AcquireList(); + delList.Add(callback); + eventDic.Add(evt, delList); } } #endregion @@ -92,7 +95,12 @@ namespace AxibugEmuOnline.Server.Event if (eventDic.ContainsKey(evt)) { eventDic[evt].Remove(callback); - if (eventDic[evt].Count == 0) eventDic.Remove(evt); + if (eventDic[evt].Count == 0) + { + //eventDic.Remove(evt); + ObjectPoolAuto.Release(eventDic[evt]); + eventDic.Remove(evt); + } } } #endregion diff --git a/AxibugEmuOnline.Server/Manager/AppSrv.cs b/AxibugEmuOnline.Server/Manager/AppSrv.cs index e69b3fd..5581c5e 100644 --- a/AxibugEmuOnline.Server/Manager/AppSrv.cs +++ b/AxibugEmuOnline.Server/Manager/AppSrv.cs @@ -20,12 +20,12 @@ namespace AxibugEmuOnline.Server public static void InitServer(int port) { + g_Log = new LogManager(); Config.LoadConfig(); Haoyue_SQLPoolManager.InitConnMgr(); g_Tick = new TickManager(); g_ClientMgr = new ClientManager(); g_ClientMgr.Init(45000, 120); - g_Log = new LogManager(); g_Login = new LoginManager(); g_Chat = new ChatManager(); g_UserMgr = new UserManager(); diff --git a/AxibugEmuOnline.Server/Manager/GameShareManager.cs b/AxibugEmuOnline.Server/Manager/GameShareManager.cs index a7ffb7f..baa0b57 100644 --- a/AxibugEmuOnline.Server/Manager/GameShareManager.cs +++ b/AxibugEmuOnline.Server/Manager/GameShareManager.cs @@ -1,10 +1,8 @@ using AxibugEmuOnline.Server.Common; -using AxibugEmuOnline.Server.Event; using AxibugEmuOnline.Server.NetWork; using AxibugProtobuf; using MySql.Data.MySqlClient; using System.Net.Sockets; -using static AxibugEmuOnline.Server.RoomManager; namespace AxibugEmuOnline.Server.Manager { diff --git a/AxibugEmuOnline.Server/Manager/LogManager.cs b/AxibugEmuOnline.Server/Manager/LogManager.cs index 8121df1..037ed52 100644 --- a/AxibugEmuOnline.Server/Manager/LogManager.cs +++ b/AxibugEmuOnline.Server/Manager/LogManager.cs @@ -1,4 +1,7 @@ -namespace AxibugEmuOnline.Server.Manager +using AxibugProtobuf; +using static Mysqlx.Expect.Open.Types; + +namespace AxibugEmuOnline.Server.Manager { public class LogManager { @@ -19,6 +22,14 @@ //Console.WriteLine(str); } + public void Assert(bool conditional, string message) + { + if (!conditional) + { + Debug(message); + } + } + public void Warning(string str) { Console.WriteLine(str); diff --git a/AxibugEmuOnline.Server/Manager/RoomManager.cs b/AxibugEmuOnline.Server/Manager/RoomManager.cs index ccb09b5..f456e9f 100644 --- a/AxibugEmuOnline.Server/Manager/RoomManager.cs +++ b/AxibugEmuOnline.Server/Manager/RoomManager.cs @@ -4,6 +4,7 @@ using AxibugEmuOnline.Server.NetWork; using AxibugProtobuf; using MySql.Data.MySqlClient; using Org.BouncyCastle.Crypto.Parameters; +using System.Collections.Generic; using System.Data; using System.Net.Sockets; using System.Runtime.InteropServices; @@ -70,6 +71,8 @@ namespace AxibugEmuOnline.Server { if (mDictRoom.ContainsKey(RoomID)) { + mDictRoom[RoomID].Dispose(); + mDictRoom.Remove(RoomID); mKeyRoomList.Remove(RoomID); } @@ -83,16 +86,14 @@ namespace AxibugEmuOnline.Server return data; } - public List GetRoomList() + public void GetRoomList(ref List roomList) { lock (mDictRoom) { - List temp = new List(); foreach (var room in mDictRoom) { - temp.AddRange(mDictRoom.Values); + roomList.AddRange(mDictRoom.Values); } - return temp; } } @@ -177,9 +178,11 @@ namespace AxibugEmuOnline.Server Protobuf_Room_List msg = ProtoBufHelper.DeSerizlize(reqData); Protobuf_Room_List_RESP resp = new Protobuf_Room_List_RESP(); - List temp = GetRoomList(); + List temp = ObjectPoolAuto.AcquireList(); + GetRoomList(ref temp); foreach (var room in temp) resp.RoomMiniInfoList.Add(GetProtoDataRoom(room)); + ObjectPoolAuto.Release(temp); AppSrv.g_ClientMgr.ClientSend(_c, (int)CommandID.CmdRoomList, (int)ErrorCode.ErrorOk, ProtoBufHelper.Serizlize(resp)); } public void CmdRoomGetScreen(Socket sk, byte[] reqData) @@ -513,12 +516,15 @@ namespace AxibugEmuOnline.Server RoomMiniInfo = GetProtoDataRoom(room) }; - List userlist = room.GetAllPlayerClientList(); + List userlist = ObjectPoolAuto.AcquireList(); + room.GetAllPlayerClientList(ref userlist); foreach (ClientInfo _c in userlist) { AppSrv.g_ClientMgr.ClientSend(_c, (int)CommandID.CmdRoomMyRoomStateChanged, (int)ErrorCode.ErrorOk, ProtoBufHelper.Serizlize(resp)); } + + ObjectPoolAuto.Release(userlist); } /// @@ -527,7 +533,10 @@ namespace AxibugEmuOnline.Server /// public void SendRoomStepChange(Data_RoomData room) { - List roomClient = room.GetAllPlayerClientList(); + + List roomClient = ObjectPoolAuto.AcquireList(); + room.GetAllPlayerClientList(ref roomClient); + switch (room.GameState) { case RoomGameState.WaitRawUpdate: @@ -562,6 +571,8 @@ namespace AxibugEmuOnline.Server } break; } + + ObjectPoolAuto.Release(roomClient); } #region 房间帧循环 @@ -591,7 +602,7 @@ namespace AxibugEmuOnline.Server #endregion } - public class Data_RoomData + public class Data_RoomData : IDisposable { public int RoomID { get; private set; } public int GameRomID { get; private set; } @@ -612,9 +623,13 @@ namespace AxibugEmuOnline.Server public uint mCurrServerFrameId = 0; public ServerInputSnapShot mCurrInputData; public Queue<(uint, ServerInputSnapShot)> mInputQueue; + + public List send2time; + const int SynLimitOnSec = 63; + object synInputLock = new object(); //TODO - public Dictionary> mDictPlayerIdx2SendQueue; + //public Dictionary> mDictPlayerIdx2SendQueue; public RoomGameState GameState { get { return mGameState; } @@ -641,6 +656,7 @@ namespace AxibugEmuOnline.Server public uint SrvForwardFrames { get; set; } public void Init(int roomID, int gameRomID, string roomHash, long hostUId, bool bloadState = false) { + Dispose(); RoomID = roomID; GameRomID = gameRomID; RomHash = roomHash; @@ -658,12 +674,39 @@ namespace AxibugEmuOnline.Server PlayerSlot[i].Init(i); //PlayerReadyState = new bool[4]; - SynUIDs = new List();//广播角色列表 + SynUIDs = ObjectPoolAuto.AcquireList();//new List();//广播角色列表 GameState = RoomGameState.NoneGameState; mCurrInputData = new ServerInputSnapShot(); - mInputQueue = new Queue<(uint, ServerInputSnapShot)>(); - mDictPlayerIdx2SendQueue = new Dictionary>(); + mInputQueue = ObjectPoolAuto.AcquireQueue<(uint, ServerInputSnapShot)>(); + // new Queue<(uint, ServerInputSnapShot)>(); + //mDictPlayerIdx2SendQueue = new Dictionary>(); + send2time = ObjectPoolAuto.AcquireList(); } + + /// + /// 房间释放时,需要调用 + /// + public void Dispose() + { + if (SynUIDs != null) + { + ObjectPoolAuto.Release(SynUIDs); + SynUIDs = null; + } + + if (mInputQueue != null) + { + ObjectPoolAuto.Release(mInputQueue); + mInputQueue = null; + } + + if (send2time != null) + { + ObjectPoolAuto.Release(send2time); + send2time = null; + } + } + public Dictionary GetSlotDataByUID(long uid) { Dictionary slotIdx2JoyIdx = new Dictionary(); @@ -736,13 +779,13 @@ namespace AxibugEmuOnline.Server else if (Player2_UID == uid) bHad = true; else if (Player3_UID == uid) bHad = true; else if (Player4_UID == uid) bHad = true; - if (bHad) + if (!bHad) SynUIDs.RemoveAt(i); } - if (!SynUIDs.Contains(Player1_UID)) SynUIDs.Add(Player1_UID); - if (!SynUIDs.Contains(Player2_UID)) SynUIDs.Add(Player2_UID); - if (!SynUIDs.Contains(Player3_UID)) SynUIDs.Add(Player3_UID); - if (!SynUIDs.Contains(Player4_UID)) SynUIDs.Add(Player4_UID); + if (Player1_UID > 0 && !SynUIDs.Contains(Player1_UID)) SynUIDs.Add(Player1_UID); + if (Player2_UID > 0 && !SynUIDs.Contains(Player2_UID)) SynUIDs.Add(Player2_UID); + if (Player3_UID > 0 && !SynUIDs.Contains(Player3_UID)) SynUIDs.Add(Player3_UID); + if (Player4_UID > 0 && !SynUIDs.Contains(Player4_UID)) SynUIDs.Add(Player4_UID); } #region 准备状态管理 @@ -790,7 +833,7 @@ namespace AxibugEmuOnline.Server public void SetPlayerSlotData(ClientInfo _c, ref readonly Dictionary newSlotIdx2JoyIdx) { Dictionary oldSlotIdx2JoyIdx = GetSlotDataByUID(_c.UID); - HashSet diffSlotIdxs = new HashSet(); + HashSet diffSlotIdxs = ObjectPoolAuto.AcquireSet();// new HashSet(); foreach (var old in oldSlotIdx2JoyIdx) { uint old_slotIdx = old.Key; @@ -830,6 +873,8 @@ namespace AxibugEmuOnline.Server //更新需要同步的UID UpdateSynUIDs(); _c.RoomState.SetRoomData(this.RoomID); + + ObjectPoolAuto.Release(diffSlotIdxs); } public void RemovePlayer(ClientInfo _c) { @@ -873,9 +918,8 @@ namespace AxibugEmuOnline.Server return true; } - public List GetAllPlayerClientList() + public void GetAllPlayerClientList(ref List list) { - List list = new List(); List Uids = SynUIDs; foreach (long uid in Uids) { @@ -883,7 +927,6 @@ namespace AxibugEmuOnline.Server continue; list.Add(_c); } - return list; } void SetInputBySlotIdxJoyIdx(uint SlotIdx, uint LocalJoyIdx, ServerInputSnapShot clieninput) @@ -902,7 +945,10 @@ namespace AxibugEmuOnline.Server } public void UpdateRoomForwardNum() { - List playerlist = GetAllPlayerClientList(); + + List playerlist = ObjectPoolAuto.AcquireList(); + GetAllPlayerClientList(ref playerlist); + double maxNetDelay = 0; for (int i = 0; i < playerlist.Count; i++) { @@ -914,13 +960,15 @@ namespace AxibugEmuOnline.Server if (SrvForwardFrames < 2) SrvForwardFrames = 2; //AppSrv.g_Log.Debug($"服务器提前跑帧数:Max(2,({maxNetDelay} / {0.016f}) + {MustTaskFrame}) = {SrvForwardFrames}"); + + ObjectPoolAuto.Release(playerlist); } #region 帧相关 void StartNewTick() { mInputQueue.Clear(); - mDictPlayerIdx2SendQueue.Clear(); + //mDictPlayerIdx2SendQueue.Clear(); mCurrServerFrameId = 0; mCurrInputData.all = 1; @@ -951,8 +999,6 @@ namespace AxibugEmuOnline.Server ulong LastTestSend = 0; internal ulong LastTestRecv; - public List send2time = new List(); - const int SynLimitOnSec = 63; /// /// 广播数据 @@ -978,7 +1024,8 @@ namespace AxibugEmuOnline.Server if (!flagInitList) { flagInitList = true; - temp = new List<(uint frameId, ServerInputSnapShot inputdata)>(); + //temp = new List<(uint frameId, ServerInputSnapShot inputdata)>(); + temp = ObjectPoolAuto.AcquireList<(uint frameId, ServerInputSnapShot inputdata)>(); } temp.Add(mInputQueue.Dequeue()); send2time.Add(timeNow); @@ -1010,6 +1057,8 @@ namespace AxibugEmuOnline.Server // AppSrv.g_Log.Debug($" {DateTime.Now.ToString("hh:mm:ss.fff")} SynInput=> RoomID->{RoomID} ServerFrameID->{mCurrServerFrameId} SynUIDs=>{string.Join(",", SynUIDs)} "); //} } + + ObjectPoolAuto.Release(temp); } bool CheckRoomStateChange(int oldPlayerCount, int newPlayerCount) @@ -1174,6 +1223,7 @@ namespace AxibugEmuOnline.Server forwaFrame = targetFrame - mCurrServerFrameId; return forwaFrame > 0; } + #endregion } diff --git a/AxibugEmuOnline.Server/NetWork/NetMsg.cs b/AxibugEmuOnline.Server/NetWork/NetMsg.cs index dec88b1..c05b0a4 100644 --- a/AxibugEmuOnline.Server/NetWork/NetMsg.cs +++ b/AxibugEmuOnline.Server/NetWork/NetMsg.cs @@ -31,7 +31,10 @@ namespace AxibugEmuOnline.Server.NetWork } else { - netEventDic.Add(cmd, new List() { callback }); + //netEventDic.Add(cmd, new List() { callback }); + List delList = ObjectPoolAuto.AcquireList(); + delList.Add(callback); + netEventDic.Add(cmd, delList); } } #endregion @@ -49,7 +52,12 @@ namespace AxibugEmuOnline.Server.NetWork if (netEventDic.ContainsKey(cmd)) { netEventDic[cmd].Remove(callback); - if (netEventDic[cmd].Count == 0) netEventDic.Remove(cmd); + if (netEventDic[cmd].Count == 0) + { + //netEventDic.Remove(cmd); + ObjectPoolAuto.Release(netEventDic[cmd]); + netEventDic.Remove(cmd); + } } } #endregion diff --git a/AxibugEmuOnline.Server/Program.cs b/AxibugEmuOnline.Server/Program.cs index adbad23..67654f1 100644 --- a/AxibugEmuOnline.Server/Program.cs +++ b/AxibugEmuOnline.Server/Program.cs @@ -21,7 +21,10 @@ namespace AxibugEmuOnline.Server { case "rlist": { - var roomlist = AppSrv.g_Room.GetRoomList(); + + List roomlist = ObjectPoolAuto.AcquireList(); + AppSrv.g_Room.GetRoomList(ref roomlist); + AppSrv.g_Log.Info($"RoomCount:{roomlist.Count}"); foreach (var room in roomlist) { @@ -55,6 +58,7 @@ namespace AxibugEmuOnline.Server } } } + ObjectPoolAuto.Release(roomlist); } break; case "list":