/************************************************************************************/ protected void KillTimer(int iTimerID) { lock (m_Lock) { TimerDesc ThisTimerDesc = null; if (!m_Timers.TryGetValue(iTimerID, out ThisTimerDesc)) { return; } m_Timers.Remove(iTimerID); ThisTimerDesc.m_Timer.Stop(); ThisTimerDesc.m_Timer.Dispose(); /// Remove the timer from the pulse table. NotifyTimerPulse(iTimerID, false); } return; }
/************************************************************************************/ protected void CreateTimer(int iNewTimerID, double fIntervalMilliseconds, object objContext) { lock (m_Lock) { if (m_Timers.ContainsKey(iNewTimerID)) { throw new Exception("Cannot create timers with duplicate ID's."); } System.Timers.Timer NewTimer = new System.Timers.Timer(); NewTimer.Interval = fIntervalMilliseconds; TimerDesc NewTimerDesc = new TimerDesc(iNewTimerID, NewTimer, this, objContext); m_Timers.Add(iNewTimerID, NewTimerDesc); NewTimer.Elapsed += new ElapsedEventHandler(NewTimerDesc.OnTimedEvent); NewTimer.Start(); // GO! } return; }
/************************************************************************************/ /// <summary> /// Retrieves a message from the queue. /// </summary> /// <remarks> /// This function will throw an exception if called from outside the context of the owner thread. /// </remarks> /// <param name="bWaitForMessageIfEmpty"></param> /// <returns>Returns NULL if no message was in the queue.</returns> protected ThreadMessage GetMessage(bool bWaitForMessageIfEmpty) { int iWaitObjectIndex = -1; if (bWaitForMessageIfEmpty) { iWaitObjectIndex = WaitHandle.WaitAny(m_aWaitHandles); // TODO: Should we figure a way to abort this? } else { iWaitObjectIndex = WaitHandle.WaitAny(m_aWaitHandles, 0, false); } WaitHandle ThisSignalledHandle = null; if (iWaitObjectIndex != WaitHandle.WaitTimeout) { ThisSignalledHandle = m_aWaitHandles[iWaitObjectIndex]; } /// If a wait was signalled and it wasn't the standard queue filled event, return it. /// The recipient has an obligation to clear the signal or unregister the handle, /// otherwise the next call to GetMessage will return the same handle. if (ThisSignalledHandle != null && ThisSignalledHandle.SafeWaitHandle != m_QueueFilledEvent.SafeWaitHandle) { return(new WaitHandleSignalledMessage(ThisSignalledHandle)); } ThreadMessage NewIncomingMessage = null; lock (m_Lock) { // Dummy check. if (m_Thread.ManagedThreadId != Thread.CurrentThread.ManagedThreadId) { throw new Exception("TekMessageThread.GetMessage can only be called from the context of the owner thread."); } /// Check for any legit messages. if (m_MessageQueue.Count > 0) { NewIncomingMessage = m_MessageQueue.Dequeue(); } /// Check our timer list and generate a pseudo-message. /// Timers have lowest priority just like Win32 because if the messages build /// up and if the message handler takes time to process (such as connection timeout), /// then the backlog of messages will drown out any other processing. else if (m_PulsedTimers.Count > 0) { int iTimerID = m_PulsedTimers[0]; m_PulsedTimers.Remove(iTimerID); TimerDesc ThisTimerDesc = m_Timers[iTimerID]; NewIncomingMessage = new TimerMessage(iTimerID, ThisTimerDesc.m_Context, ThisTimerDesc.m_Timer.Interval); } /// Now that there is NOTHING to retrieve, make the event block again. if (QueuedMessageCount == 0) { m_QueueFilledEvent.Reset(); } } return(NewIncomingMessage); }