public static TimerInfo Create(IContext context, ISecurityRt security, TimeSpan recalcTime) { var delayMs = GetInterval(recalcTime); var timerInfo = new TimerInfo(context, security); var timer = TimerFactory.CreateThreadingTimer(Recalculate, timerInfo, delayMs, new TimeSpan(24, 0, 0)); timerInfo.Timer = timer; return(timerInfo); }
private void Recalculate(ISecurity sec) { //Context.Log(String.Format("[Heartbeat.Execute ( ID:{0} )] I'm checking timer settings.", m_id), MessageType.Warning, false); CallState timerState = null; string cashKey = VariableId + "_timerState"; { object localObj = Context.LoadObject(cashKey, false); timerState = localObj as CallState; // PROD-3970 - 'Важный' объект if (timerState == null) { var container = localObj as NotClearableContainer; if ((container != null) && (container.Content != null)) { timerState = container.Content as CallState; } } } //m_timer = Context.LoadObject(VariableId + "m_timer") as IThreadingTimerProfiler; if (timerState == null) { string msg = String.Format("[Heartbeat.Execute ( ID:{0} )] Preparing new timer for agent '{1}'...", m_id, Context.Runtime.TradeName); Context.Log(msg, MessageType.Info, false); timerState = new CallState(m_id, Context, sec.SecurityDescription, m_onlyAtTradingSession); var timer = TimerFactory.CreateThreadingTimer(Recalculate, timerState, m_delayMs, Timeout.Infinite); // Обязательно дозаполняем ссылку на таймер timerState.Timer = timer; var container = new NotClearableContainer(timerState); Context.StoreObject(cashKey, container, false); } else if (timerState.Timer == null) { // PROD-5427 - Добавляю счетчик этого аварийного события и логгирую int problemCounter = 0; if (s_problemCounters.ContainsKey(Context.Runtime.TradeName)) { problemCounter = s_problemCounters[Context.Runtime.TradeName]; } s_problemCounters[Context.Runtime.TradeName] = Interlocked.Increment(ref problemCounter); string msg = String.Format("[Heartbeat.Execute ( ID:{0} )] Timer is null in agent '{1}'. Problem counter: {2}", m_id, Context.Runtime.TradeName, problemCounter); Context.Log(msg, MessageType.Warning, false); if (problemCounter > 3) { // Если проблема систематически повторяется -- выбрасываю ассерт для дальнейшего анализа ситуации Contract.Assert(timerState.Timer != null, msg); } } else { //Contract.Assert(timerState.Timer != null, "Почему вдруг (timerState.Timer==null) ??"); // Если при изменении скрипта пересоздается агент, то контекст становится невалидным? if (Object.ReferenceEquals(Context, timerState.CallContext)) { // Если контекст совпадает, то обновляем режим работы... timerState.OnlyAtTradingSession = m_onlyAtTradingSession; // и перезапускаем таймер try { timerState.Timer.Change(m_delayMs, Timeout.Infinite); // PROD-5427 - При штатной работе блока обнуляю счетчик проблем s_problemCounters[Context.Runtime.TradeName] = 0; } catch (ObjectDisposedException) { // Если таймер уже убит, то надо создать новый timerState.Timer = null; timerState = null; string msg = String.Format("[Heartbeat.Execute ( ID:{0} )] Replacing DISPOSED timer for agent '{1}'...", m_id, Context.Runtime.TradeName); Context.Log(msg, MessageType.Warning, false); // Создаём новый таймер. При этом используем НОВЫЙ m_id timerState = new CallState(m_id, Context, sec.SecurityDescription, m_onlyAtTradingSession); var timer = TimerFactory.CreateThreadingTimer(Recalculate, timerState, m_delayMs, Timeout.Infinite); // Обязательно дозаполняем ссылку на таймер timerState.Timer = timer; var container = new NotClearableContainer(timerState); Context.StoreObject(cashKey, container, false); } } else { // Если по какой-то причине изменился контекст, то создаём новый таймер... timerState.Timer.Dispose(); timerState.Timer = null; timerState = null; string msg = String.Format("[Heartbeat.Execute ( ID:{0} )] Replacing timer for agent '{1}'...", m_id, Context.Runtime.TradeName); Context.Log(msg, MessageType.Warning, false); // Создаём новый таймер. При этом используем НОВЫЙ m_id timerState = new CallState(m_id, Context, sec.SecurityDescription, m_onlyAtTradingSession); var timer = TimerFactory.CreateThreadingTimer(Recalculate, timerState, m_delayMs, Timeout.Infinite); // Обязательно дозаполняем ссылку на таймер timerState.Timer = timer; var container = new NotClearableContainer(timerState); Context.StoreObject(cashKey, container, false); } } }