DispatcherTimer.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ Net / Net / 3.5.50727.3053 / DEVDIV / depot / DevDiv / releases / Orcas / SP / wpf / src / Base / System / Windows / Threading / DispatcherTimer.cs / 1 / DispatcherTimer.cs

                            using System; 
using System.Threading;
using System.Windows;
using System.Diagnostics;
using System.Collections.Generic; 

namespace System.Windows.Threading 
{ 
    /// 
    ///     A timer that is integrated into the Dispatcher queues, and will 
    ///     be processed after a given amount of time at a specified priority.
    /// 
    public class DispatcherTimer
    { 
        /// 
        ///     Creates a timer that uses the current thread's Dispatcher to 
        ///     process the timer event at background priority. 
        /// 
        public DispatcherTimer() : this(DispatcherPriority.Background)  // NOTE: should be Priority Dispatcher.BackgroundPriority 
        {
        }

        ///  
        ///     Creates a timer that uses the current thread's Dispatcher to
        ///     process the timer event at the specified priority. 
        ///  
        /// 
        ///     The priority to process the timer at. 
        /// 
        public DispatcherTimer(DispatcherPriority priority) // NOTE: should be Priority
        {
            Initialize(Dispatcher.CurrentDispatcher, priority, TimeSpan.FromMilliseconds(0)); 
        }
 
        ///  
        ///     Creates a timer that uses the specified Dispatcher to
        ///     process the timer event at the specified priority. 
        /// 
        /// 
        ///     The priority to process the timer at.
        ///  
        /// 
        ///     The dispatcher to use to process the timer. 
        ///  
        public DispatcherTimer(DispatcherPriority priority, Dispatcher dispatcher)  // NOTE: should be Priority
        { 
            if(dispatcher == null)
            {
                throw new ArgumentNullException("dispatcher");
            } 

            Initialize(dispatcher, priority, TimeSpan.FromMilliseconds(0)); 
        } 

        ///  
        ///     Creates a timer that is bound to the specified dispatcher and
        ///     will be processed at the specified priority, after the
        ///     specified timeout.
        ///  
        /// 
        ///     The interval to tick the timer after. 
        ///  
        /// 
        ///     The priority to process the timer at. 
        /// 
        /// 
        ///     The callback to call when the timer ticks.
        ///  
        /// 
        ///     The dispatcher to use to process the timer. 
        ///  
        public DispatcherTimer(TimeSpan interval, DispatcherPriority priority, EventHandler callback, Dispatcher dispatcher) // NOTE: should be Priority
        { 
            //


 

 
 
            if(callback == null)
            { 
                throw new ArgumentNullException("callback");
            }
            if(dispatcher == null)
            { 
                throw new ArgumentNullException("dispatcher");
            } 
 
            if (interval.TotalMilliseconds < 0)
                throw new ArgumentOutOfRangeException("interval", SR.Get(SRID.TimeSpanPeriodOutOfRange_TooSmall)); 

            if (interval.TotalMilliseconds > Int32.MaxValue)
                throw new ArgumentOutOfRangeException("interval", SR.Get(SRID.TimeSpanPeriodOutOfRange_TooLarge));
 
            Initialize(dispatcher, priority, interval);
 
            Tick += callback; 
            Start();
        } 

        /// 
        ///     Gets the dispatcher this timer is associated with.
        ///  
        public Dispatcher Dispatcher
        { 
            get 
            {
                return _dispatcher; 
            }
        }

        ///  
        ///     Gets or sets whether the timer is running.
        ///  
        public bool IsEnabled 
        {
            get 
            {
                return _isEnabled;
            }
 
            set
            { 
                lock(_instanceLock) 
                {
                    if(!value && _isEnabled) 
                    {
                        Stop();
                    }
                    else if(value && !_isEnabled) 
                    {
                        Start(); 
                    } 
                }
            } 
        }

        /// 
        ///     Gets or sets the time between timer ticks. 
        /// 
        public TimeSpan Interval 
        { 
            get
            { 
                return _interval;
            }

            set 
            {
                bool updateWin32Timer = false; 
 
                if (value.TotalMilliseconds < 0)
                    throw new ArgumentOutOfRangeException("value", SR.Get(SRID.TimeSpanPeriodOutOfRange_TooSmall)); 

                if (value.TotalMilliseconds > Int32.MaxValue)
                    throw new ArgumentOutOfRangeException("value", SR.Get(SRID.TimeSpanPeriodOutOfRange_TooLarge));
 
                lock(_instanceLock)
                { 
                    _interval = value; 

                    if(_isEnabled) 
                    {
                        _dueTimeInTicks = Environment.TickCount + (int)_interval.TotalMilliseconds;
                        updateWin32Timer = true;
                    } 
                }
 
                if(updateWin32Timer) 
                {
                    _dispatcher.UpdateWin32Timer(); 
                }
            }
        }
 
        /// 
        ///     Starts the timer. 
        ///  
        public void Start()
        { 
            lock(_instanceLock)
            {
                if(!_isEnabled)
                { 
                    _isEnabled = true;
 
                    Restart(); 
                }
            } 
        }

        /// 
        ///     Stops the timer. 
        /// 
        public void Stop() 
        { 
            bool updateWin32Timer = false;
 
            lock(_instanceLock)
            {
                if(_isEnabled)
                { 
                    _isEnabled = false;
                    updateWin32Timer = true; 
 
                    // If the operation is in the queue, abort it.
                    if(_operation != null) 
                    {
                        _operation.Abort();
                        _operation = null;
                    } 

                } 
            } 

            if(updateWin32Timer) 
            {
                _dispatcher.RemoveTimer(this);
            }
        } 

        ///  
        ///     Occurs when the specified timer interval has elapsed and the 
        ///     timer is enabled.
        ///  
        public event EventHandler Tick;

        /// 
        ///     Any data that the caller wants to pass along with the timer. 
        /// 
        public object Tag 
        { 
            get
            { 
                return _tag;
            }

            set 
            {
                _tag = value; 
            } 
        }
 

        private void Initialize(Dispatcher dispatcher, DispatcherPriority priority, TimeSpan interval)
        {
            // Note: all callers of this have a "priority" parameter. 
            Dispatcher.ValidatePriority(priority, "priority");
            if(priority == DispatcherPriority.Inactive) 
            { 
                throw new ArgumentException(SR.Get(SRID.InvalidPriority), "priority");
            } 

            _dispatcher = dispatcher;
            _priority = priority;
            _interval = interval; 
        }
 
        private void Restart() 
        {
            lock(_instanceLock) 
            {
                if (_operation != null)
                {
                    // Timer has already been restarted, e.g. Start was called form the Tick handler. 
                    return;
                } 
 
                // BeginInvoke a new operation.
                _operation = _dispatcher.BeginInvoke( 
                    DispatcherPriority.Inactive,
                    new DispatcherOperationCallback(FireTick),
                    null);
 

                _dueTimeInTicks = Environment.TickCount + (int) _interval.TotalMilliseconds; 
 
                if (_interval.TotalMilliseconds == 0 && _dispatcher.CheckAccess())
                { 
                    // shortcut - just promote the item now
                    Promote();
                }
                else 
                {
                    _dispatcher.AddTimer(this); 
                } 
            }
 
        }

        internal void Promote() // called from Dispatcher
        { 
            lock(_instanceLock)
            { 
                // Simply promote the operation to it's desired priority. 
                if(_operation != null)
                { 
                    _operation.Priority = _priority;
                }
            }
        } 

        private object FireTick(object unused) 
        { 
            // The operation has been invoked, so forget about it.
            _operation = null; 

            // The dispatcher thread is calling us because item's priority
            // was changed from inactive to something else.
            if(Tick != null) 
            {
                Tick(this, EventArgs.Empty); 
            } 

            // If we are still enabled, start the timer again. 
            if(_isEnabled)
            {
                Restart();
            } 

            return null; 
        } 

        // This is the object we use to synchronize access. 
        private object _instanceLock = new object();

        // Note: We cannot BE a dispatcher-affinity object because we can be
        // created by a worker thread.  We are still associated with a 
        // dispatcher (where we post the item) but we can be accessed
        // by any thread. 
        private Dispatcher _dispatcher; 

        private DispatcherPriority _priority;  // NOTE: should be Priority 
        private TimeSpan _interval;
        private object _tag;
        private DispatcherOperation _operation;
        private bool _isEnabled; 

        internal int _dueTimeInTicks; // used by Dispatcher 
    } 
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
using System; 
using System.Threading;
using System.Windows;
using System.Diagnostics;
using System.Collections.Generic; 

namespace System.Windows.Threading 
{ 
    /// 
    ///     A timer that is integrated into the Dispatcher queues, and will 
    ///     be processed after a given amount of time at a specified priority.
    /// 
    public class DispatcherTimer
    { 
        /// 
        ///     Creates a timer that uses the current thread's Dispatcher to 
        ///     process the timer event at background priority. 
        /// 
        public DispatcherTimer() : this(DispatcherPriority.Background)  // NOTE: should be Priority Dispatcher.BackgroundPriority 
        {
        }

        ///  
        ///     Creates a timer that uses the current thread's Dispatcher to
        ///     process the timer event at the specified priority. 
        ///  
        /// 
        ///     The priority to process the timer at. 
        /// 
        public DispatcherTimer(DispatcherPriority priority) // NOTE: should be Priority
        {
            Initialize(Dispatcher.CurrentDispatcher, priority, TimeSpan.FromMilliseconds(0)); 
        }
 
        ///  
        ///     Creates a timer that uses the specified Dispatcher to
        ///     process the timer event at the specified priority. 
        /// 
        /// 
        ///     The priority to process the timer at.
        ///  
        /// 
        ///     The dispatcher to use to process the timer. 
        ///  
        public DispatcherTimer(DispatcherPriority priority, Dispatcher dispatcher)  // NOTE: should be Priority
        { 
            if(dispatcher == null)
            {
                throw new ArgumentNullException("dispatcher");
            } 

            Initialize(dispatcher, priority, TimeSpan.FromMilliseconds(0)); 
        } 

        ///  
        ///     Creates a timer that is bound to the specified dispatcher and
        ///     will be processed at the specified priority, after the
        ///     specified timeout.
        ///  
        /// 
        ///     The interval to tick the timer after. 
        ///  
        /// 
        ///     The priority to process the timer at. 
        /// 
        /// 
        ///     The callback to call when the timer ticks.
        ///  
        /// 
        ///     The dispatcher to use to process the timer. 
        ///  
        public DispatcherTimer(TimeSpan interval, DispatcherPriority priority, EventHandler callback, Dispatcher dispatcher) // NOTE: should be Priority
        { 
            //


 

 
 
            if(callback == null)
            { 
                throw new ArgumentNullException("callback");
            }
            if(dispatcher == null)
            { 
                throw new ArgumentNullException("dispatcher");
            } 
 
            if (interval.TotalMilliseconds < 0)
                throw new ArgumentOutOfRangeException("interval", SR.Get(SRID.TimeSpanPeriodOutOfRange_TooSmall)); 

            if (interval.TotalMilliseconds > Int32.MaxValue)
                throw new ArgumentOutOfRangeException("interval", SR.Get(SRID.TimeSpanPeriodOutOfRange_TooLarge));
 
            Initialize(dispatcher, priority, interval);
 
            Tick += callback; 
            Start();
        } 

        /// 
        ///     Gets the dispatcher this timer is associated with.
        ///  
        public Dispatcher Dispatcher
        { 
            get 
            {
                return _dispatcher; 
            }
        }

        ///  
        ///     Gets or sets whether the timer is running.
        ///  
        public bool IsEnabled 
        {
            get 
            {
                return _isEnabled;
            }
 
            set
            { 
                lock(_instanceLock) 
                {
                    if(!value && _isEnabled) 
                    {
                        Stop();
                    }
                    else if(value && !_isEnabled) 
                    {
                        Start(); 
                    } 
                }
            } 
        }

        /// 
        ///     Gets or sets the time between timer ticks. 
        /// 
        public TimeSpan Interval 
        { 
            get
            { 
                return _interval;
            }

            set 
            {
                bool updateWin32Timer = false; 
 
                if (value.TotalMilliseconds < 0)
                    throw new ArgumentOutOfRangeException("value", SR.Get(SRID.TimeSpanPeriodOutOfRange_TooSmall)); 

                if (value.TotalMilliseconds > Int32.MaxValue)
                    throw new ArgumentOutOfRangeException("value", SR.Get(SRID.TimeSpanPeriodOutOfRange_TooLarge));
 
                lock(_instanceLock)
                { 
                    _interval = value; 

                    if(_isEnabled) 
                    {
                        _dueTimeInTicks = Environment.TickCount + (int)_interval.TotalMilliseconds;
                        updateWin32Timer = true;
                    } 
                }
 
                if(updateWin32Timer) 
                {
                    _dispatcher.UpdateWin32Timer(); 
                }
            }
        }
 
        /// 
        ///     Starts the timer. 
        ///  
        public void Start()
        { 
            lock(_instanceLock)
            {
                if(!_isEnabled)
                { 
                    _isEnabled = true;
 
                    Restart(); 
                }
            } 
        }

        /// 
        ///     Stops the timer. 
        /// 
        public void Stop() 
        { 
            bool updateWin32Timer = false;
 
            lock(_instanceLock)
            {
                if(_isEnabled)
                { 
                    _isEnabled = false;
                    updateWin32Timer = true; 
 
                    // If the operation is in the queue, abort it.
                    if(_operation != null) 
                    {
                        _operation.Abort();
                        _operation = null;
                    } 

                } 
            } 

            if(updateWin32Timer) 
            {
                _dispatcher.RemoveTimer(this);
            }
        } 

        ///  
        ///     Occurs when the specified timer interval has elapsed and the 
        ///     timer is enabled.
        ///  
        public event EventHandler Tick;

        /// 
        ///     Any data that the caller wants to pass along with the timer. 
        /// 
        public object Tag 
        { 
            get
            { 
                return _tag;
            }

            set 
            {
                _tag = value; 
            } 
        }
 

        private void Initialize(Dispatcher dispatcher, DispatcherPriority priority, TimeSpan interval)
        {
            // Note: all callers of this have a "priority" parameter. 
            Dispatcher.ValidatePriority(priority, "priority");
            if(priority == DispatcherPriority.Inactive) 
            { 
                throw new ArgumentException(SR.Get(SRID.InvalidPriority), "priority");
            } 

            _dispatcher = dispatcher;
            _priority = priority;
            _interval = interval; 
        }
 
        private void Restart() 
        {
            lock(_instanceLock) 
            {
                if (_operation != null)
                {
                    // Timer has already been restarted, e.g. Start was called form the Tick handler. 
                    return;
                } 
 
                // BeginInvoke a new operation.
                _operation = _dispatcher.BeginInvoke( 
                    DispatcherPriority.Inactive,
                    new DispatcherOperationCallback(FireTick),
                    null);
 

                _dueTimeInTicks = Environment.TickCount + (int) _interval.TotalMilliseconds; 
 
                if (_interval.TotalMilliseconds == 0 && _dispatcher.CheckAccess())
                { 
                    // shortcut - just promote the item now
                    Promote();
                }
                else 
                {
                    _dispatcher.AddTimer(this); 
                } 
            }
 
        }

        internal void Promote() // called from Dispatcher
        { 
            lock(_instanceLock)
            { 
                // Simply promote the operation to it's desired priority. 
                if(_operation != null)
                { 
                    _operation.Priority = _priority;
                }
            }
        } 

        private object FireTick(object unused) 
        { 
            // The operation has been invoked, so forget about it.
            _operation = null; 

            // The dispatcher thread is calling us because item's priority
            // was changed from inactive to something else.
            if(Tick != null) 
            {
                Tick(this, EventArgs.Empty); 
            } 

            // If we are still enabled, start the timer again. 
            if(_isEnabled)
            {
                Restart();
            } 

            return null; 
        } 

        // This is the object we use to synchronize access. 
        private object _instanceLock = new object();

        // Note: We cannot BE a dispatcher-affinity object because we can be
        // created by a worker thread.  We are still associated with a 
        // dispatcher (where we post the item) but we can be accessed
        // by any thread. 
        private Dispatcher _dispatcher; 

        private DispatcherPriority _priority;  // NOTE: should be Priority 
        private TimeSpan _interval;
        private object _tag;
        private DispatcherOperation _operation;
        private bool _isEnabled; 

        internal int _dueTimeInTicks; // used by Dispatcher 
    } 
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK