using System.Collections.Concurrent; using System.Threading; using ActorCore; using MrWu.Debug; namespace Server.Core { public class ThreadScheduler : IScheduler { private readonly ConcurrentDictionary _dictionary = new ConcurrentDictionary(); private readonly ActorManager _actorManager; public ThreadScheduler(ActorManager actorManager) { this._actorManager = actorManager; } private void Loop(int actorTypeId) { #if DEBUG uint threadId = ThreadHelper.GetOSThreadId(); Debug.Info($"ThreadStart ThreadScheduler {threadId} {Thread.CurrentThread.ManagedThreadId} {actorTypeId}"); #endif IActor actor = _actorManager.Get(actorTypeId); ActorManager.Current = null; SynchronizationContext.SetSynchronizationContext(actor.ThreadSynchronizationContext); while (true) { if (this._actorManager.IsDisposed()) { return; } actor = _actorManager.Get(actorTypeId); if (actor == null) { this._dictionary.TryRemove(actorTypeId, out _); return; } if (actor.IsDisposed) { this._dictionary.TryRemove(actorTypeId, out _); return; } actor.IUpdate(); actor.ILateUpdate(); actor.ThreadSynchronizationContext.Update(); Thread.Sleep(1); } } public void Add(int actorTypeId) { Thread thread = new Thread(() => this.Loop(actorTypeId)); this._dictionary.TryAdd(actorTypeId, thread); thread.Start(); } public void Dispose() { foreach (var kv in this._dictionary.ToArray()) { kv.Value.Join(); } } } }