/// <summary> /// Create a repeating timer. Since the MamaTimer relies on the timer mechanism of the /// underlying middleware, the resolution of the timer is also dependent on the /// middleware. Consult your middleware documentation for details. /// The callback is invoked repeatedly at the specified interval until the timer /// is destroyed. /// A null value for the queue uses the default mama queue. /// </summary> /// <param name="queue"> /// The queue from which the timer event will be dispatched. /// </param> /// <param name="action"> /// The callback to be invoked after the interval /// </param> /// <param name="interval"> /// The interval in seconds. /// </param> /// <param name="closure"> /// Closure data for timer. /// </param> public void create(MamaQueue queue, MamaTimerCallback action, double interval, object closure) { // Check the arguments if (null == queue) { throw new ArgumentNullException("queue"); } if (null == action) { throw new ArgumentNullException("action"); } // Create the impl IntPtr impl = MamaTimerImpl.Create(action, closure, this); /* Create the timer, register for the destroy callback regardless if the client wants it or not, * this is to allow clean-up to be done whenever the timer has been fully destroyed. */ IntPtr nativeTimer = IntPtr.Zero; CheckResultCode(NativeMethods.mamaTimer_create2(ref nativeTimer, queue.NativeHandle, mTickDelegate, mDestroyDelegate, interval, impl)); // Save the native timer in the member variable NativeHandle = nativeTimer; }
/// <summary> /// This event handler is called whenever the timer ticks and will simply cause the appropriate /// callback function to be invoked. /// </summary> /// <param name="timer"> /// The native timer. /// </param> /// <param name="closure"> /// The closure passed down to the native layer. /// </param> private static void onTimerTick(IntPtr timer, IntPtr closure) { // Obtain the handle from the closure GCHandle handle = (GCHandle)closure; // Extract the impl from the handle MamaTimerImpl impl = (MamaTimerImpl)handle.Target; // Use the impl to invoke the tick callback impl.InvokeTick(); }
/* ************************************************************** */ #region Internal Operations /// <summary> /// This function creates a new impl and returns an IntPtr that can then be passed to /// the native layer. /// </summary> /// <param name="callback"> /// The user callback implementation /// </param> /// <param name="closure"> /// The closure supplied to the MamaTimer.create function. /// </param> /// <param name="timer"> /// The actual C# timer object. /// </param> /// <returns> /// The IntPtr that can then be used for the closure. /// </returns> internal static IntPtr Create(MamaTimerCallback callback, object closure, MamaTimer timer) { // Allocate a new impl MamaTimerImpl impl = new MamaTimerImpl(callback, closure, timer); // Create a GC handle GCHandle handle = GCHandle.Alloc(impl); // Return the native pointer return((IntPtr)handle); }
/* ************************************************************** */ #region Private Static Functions /// <summary> /// This event handler is called by the native layer whenever the timer has been fully destroyed. /// It will perform all clean-up and then invoke the onDestroy callback function if this has /// been supplied. /// </summary> /// <param name="timer"> /// The native timer. /// </param> /// <param name="closure"> /// The closure passed down to the native layer. /// </param> private static void onTimerDestroy(IntPtr timer, IntPtr closure) { // Obtain the handle from the closure GCHandle handle = (GCHandle)closure; // Extract the impl from the handle MamaTimerImpl impl = (MamaTimerImpl)handle.Target; // Use the impl to invoke the destroy callback, (if this has been supplied) impl.InvokeDestroy(); /* The timer has now been destroyed and the impl is no longer required, free the handle to * allow the garbage collector to clean it up. */ handle.Free(); }
/* ************************************************************** */ #region Internal Operations /// <summary> /// This function creates a new impl and returns an IntPtr that can then be passed to /// the native layer. /// </summary> /// <param name="callback"> /// The user callback implementation /// </param> /// <param name="closure"> /// The closure supplied to the MamaTimer.create function. /// </param> /// <param name="timer"> /// The actual C# timer object. /// </param> /// <returns> /// The IntPtr that can then be used for the closure. /// </returns> internal static IntPtr Create(MamaTimerCallback callback, object closure, MamaTimer timer) { // Allocate a new impl MamaTimerImpl impl = new MamaTimerImpl(callback, closure, timer); // Create a GC handle GCHandle handle = GCHandle.Alloc(impl); // Return the native pointer return (IntPtr)handle; }