public CallbackContext(WaitableTimerCallback cb, object state)
 {
     callback = cb;
     callbackState = state;
 }
 public int Change(TimeSpan dueTime, int period, WaitableTimerCallback callback, object state, bool resume)
 {
     long dueTicks = dueTime.Ticks;
     if (dueTicks < 0)
     {
         throw new ArgumentException("dueTime cannot be negative");
     }
     return ChangeInternal(-dueTicks, period, callback, state, resume);
 }
        private int ChangeInternal(long dueTime, int period, WaitableTimerCallback callback, object state, bool resume)
        {
            if (period < 0)
            {
                throw new ArgumentException("period cannot be negative.");
            }

            // CallbackContext is used to avoid a race condition.
            CallbackContext context = null;
            Win32WaitableTimer.TimerAPCProc completionCallback = null;
            if (callback != null)
            {
                context = new CallbackContext(callback, state);
                completionCallback = context.TimerTick;
            }

            // Have to do this because SetWaitableTimer needs a reference
            long due = dueTime;
            bool rslt = Win32WaitableTimer.SetWaitableTimer(
                SafeWaitHandle,
                ref due,
                period,
                completionCallback,
                IntPtr.Zero,
                resume);
            if (!rslt)
            {
                throw GetWin32Exception();
            }
            TimerCompletionCallback = context;
            return Marshal.GetLastWin32Error();
        }
 public int Change(DateTime dueTime, int period, WaitableTimerCallback callback, object state, bool resume)
 {
     long dueTicks = dueTime.ToUniversalTime().Ticks;
     return ChangeInternal(dueTicks, period, callback, state, resume);
 }