public static void Log(ThreadWorker iWorker, string iMessage, bool iLogToConsole = false) { #if WDEBUG if (!logging) { return; } if (Logs.Count > 50000) { Logs.RemoveRange(0, 20000); } var logEntity = new ThreadLogEntity { worker = iWorker, name = iMessage, stage = iWorker.stage, stop = iWorker.stop, threadId = Thread.CurrentThread.ManagedThreadId }; if (iWorker.threadCondition != null) { logEntity.threadCondition = iWorker.threadCondition() ? ThreadLogEntity.ConditionMet.True : ThreadLogEntity.ConditionMet.False; } if (iWorker.applyCondition != null) { logEntity.applyCondition = iWorker.applyCondition() ? ThreadLogEntity.ConditionMet.True : ThreadLogEntity.ConditionMet.False; } logEntity.time = DateTime.Now; logEntity.locked = iWorker.lockWasTaken; Logs.Add(logEntity); #endif if (iLogToConsole) { Loger.Error($"ThreadWorker::Log():Worker:{iWorker.name} {iMessage}"); } }
/// <summary> /// 更新应用 /// </summary> public static void UpdateApply() { if (!on || queue.Count == 0) { return; } #if WDEBUG Profiler.BeginSample("Update Apply"); #endif var timer = new System.Diagnostics.Stopwatch(); timer.Start(); while (timer.ElapsedMilliseconds < maxApplyTime) { //if couroutine has started - moving coroutine if (CurrentCoroutine != null) { currentCoroutineWorker.CoroutineFn(); continue; } //finding suitable worker with highest priority float maxProirity = -2000000; // int maxProirityNum = -1; ThreadWorker maxPriorityWorker = null; int queueCount = queue.Count; for (int i = 0; i < queueCount; i++) { ThreadWorker worker = queue[i]; if (worker == null) { continue; //if object destroyed } if (worker.priority < maxProirity) { continue; } if (worker.stage != Stage.applyEnqueued && worker.stage != Stage.prepareEnqueued && worker.stage != Stage.coroutineEnqueued && worker.stage != Stage.coroutineRunning) { continue; //other stage } if (worker.stage == Stage.prepareEnqueued && worker.prepareCondition != null && !worker.prepareCondition()) { continue; } if (worker.stage == Stage.applyEnqueued && worker.applyCondition != null && !worker.applyCondition()) { continue; //if apply condition has not met } if (worker.stage == Stage.coroutineEnqueued && worker.coroutineCondition != null && !worker.coroutineCondition()) { continue; //if coroutine condition has not met (note that conditions is checked only before starting coroutine) } maxPriorityWorker = worker; maxProirity = worker.priority; // maxProirityNum = i; } //no suitable applies if (maxPriorityWorker == null) { break; } //apply //lock (maxPriorityWorker.locker) Monitor.Enter(maxPriorityWorker.locker); maxPriorityWorker.lockWasTaken = true; try { if (logging) { Log(maxPriorityWorker, "Refresh:ApplyPrepSelected"); } if (maxPriorityWorker.stage == Stage.prepareEnqueued) { //maxPriorityWorker.SwitchStage(Stage.applyRunning); maxPriorityWorker.PrepareFn(); } if (maxPriorityWorker.stage == Stage.applyEnqueued) { //maxPriorityWorker.SwitchStage(Stage.applyRunning); maxPriorityWorker.ApplyFn(); } if (maxPriorityWorker.stage == Stage.coroutineEnqueued || maxPriorityWorker.stage == Stage.coroutineRunning) { maxPriorityWorker.CoroutineFn(); } } finally { Monitor.Exit(maxPriorityWorker.locker); maxPriorityWorker.lockWasTaken = false; } } #if WDEBUG Profiler.EndSample(); #endif }