/// <summary> /// Cslled to send refresh events to client. /// </summary> private void DoRefresh(object state) { try { // check if disposed. if (m_disposed) { return; } // send a dummy callback after a cancel. if (state == null) { IComAeEventCallback callback = m_callback; if (callback != null) { callback.OnEvent( ClientHandle, true, true, null); } return; } Queue <AeEvent> eventsToSend = null; lock (m_lock) { // check if refresh has been cancelled. if (!Object.ReferenceEquals(state, m_refreshQueue)) { return; } // clear the queue to indicate operation is complete. eventsToSend = m_refreshQueue; m_refreshQueue = null; } // send the events to client. SendInBlocks(m_callback, eventsToSend, MaxSize, true); } catch (Exception exception) { Utils.Trace(exception, "Error processing refresh callback."); } }
/// <summary> /// Sets the callback. /// </summary> /// <param name="callback">The callback.</param> public void SetCallback(IComAeEventCallback callback) { ThrowIfDisposed(); lock (m_lock) { if (m_callback != null) { m_callback.Dispose(); m_callback = null; } m_callback = callback; } }
/// <summary> /// Sends the queued events in blocks. /// </summary> private void SendInBlocks(IComAeEventCallback callback, Queue <AeEvent> events, uint blockSize, bool refreshFlag) { if (callback == null) { return; } if (blockSize == 0) { blockSize = (uint)events.Count; } while (events.Count > 0) { List <ONEVENTSTRUCT> eventsInBlock = new List <ONEVENTSTRUCT>(); try { for (int ii = 0; ii < blockSize && events.Count > 0; ii++) { // warning - Translate() allocates unmanaged memory that is deleted in the finally block. eventsInBlock.Add(Translate(events.Dequeue())); } // invoke callback. callback.OnEvent( ClientHandle, refreshFlag, (refreshFlag)?events.Count == 0:false, eventsInBlock.ToArray()); } finally { // must deallocate attributes on exit. for (int ii = 0; ii < eventsInBlock.Count; ii++) { IntPtr pAttributes = eventsInBlock[ii].pEventAttributes; ComUtils.GetVARIANTs(ref pAttributes, eventsInBlock[ii].dwNumEventAttrs, true); } } } }
/// <summary> /// Sends the queued events in blocks. /// </summary> private void SendInBlocks(IComAeEventCallback callback, Queue<AeEvent> events, uint blockSize, bool refreshFlag) { if (callback == null) { return; } if (blockSize == 0) { blockSize = (uint)events.Count; } while (events.Count > 0) { List<ONEVENTSTRUCT> eventsInBlock = new List<ONEVENTSTRUCT>(); try { for (int ii = 0; ii < blockSize && events.Count > 0; ii++) { // warning - Translate() allocates unmanaged memory that is deleted in the finally block. eventsInBlock.Add(Translate(events.Dequeue())); } // invoke callback. callback.OnEvent( ClientHandle, refreshFlag, (refreshFlag)?events.Count == 0:false, eventsInBlock.ToArray()); } finally { // must deallocate attributes on exit. for (int ii = 0; ii < eventsInBlock.Count; ii++) { IntPtr pAttributes = eventsInBlock[ii].pEventAttributes; ComUtils.GetVARIANTs(ref pAttributes, eventsInBlock[ii].dwNumEventAttrs, true); } } } }
/// <summary> /// Called send events to client. /// </summary> private void DoProcessQueue(object state) { Queue <AeEvent> events = new Queue <AeEvent>(); try { // check if disposed. if (m_disposed) { return; } // process the queue. lock (m_queue) { while (m_queue.Count > 0) { events.Enqueue(m_queue.Dequeue()); } } // check if time for a keep alive. lock (m_lock) { // check if time for keep alive. if (events.Count == 0) { if (KeepAlive == 0 || m_lastUpdateTime.AddMilliseconds(KeepAlive * m_keepAliveCount) > DateTime.UtcNow) { return; } } // no keep alives if not active. if (!Active) { return; } // update counters. if (events.Count > 0) { m_lastUpdateTime = DateTime.UtcNow; m_keepAliveCount = 1; } else { m_keepAliveCount++; } } // send a keep alive callback. if (events.Count == 0) { IComAeEventCallback callback = m_callback; if (callback != null) { callback.OnEvent( ClientHandle, false, false, null); } return; } // send the events to client. SendInBlocks(m_callback, events, MaxSize, false); } catch (Exception exception) { Utils.Trace(exception, "Error processing event callback."); } }