user857521
user857521

Reputation:

WPF Multiple Timer Control

I searched a few links for Timer Control for both Windows and WPF applications but I would appreciate some advice on my situation...

As I'm using WPF it seems initial options are either System.Windows.Threading.DispatcherTimer or System.Diagnostics.Stopwatch

What I need to achieve is for each WPF DocumentPanel to request an update from an external API at a defined interval between typically 100ms Min - anytime Max with the interval unique to each DocumentPanel. Eg DP1 could be 100ms, DP2 could be 20,000ms etc.

Normally my app would start with 1 DocumentPanel but the user can expand panels without limit so it's the users judgement on CPU ability and speed of app.

Criteria include:

  1. Multiple DocumentPanels - Typically 1 - 20 minimum but any advice on scalability is welcome.

  2. Variable event interval (Iv) (Minimum event interval 100ms - Max < 1day)

  3. Accuracy - 1ms (cannot have interval below (Iv)ms under ANY circumstances, over is not as much concern but needs to be be within several ms) EDIT: 1ms is not strictly a requirement but average (Iv) must be maintained over a short timescale.

  4. Each DocumentPanel must display live date/time but produce events based on set interval

I'm really after help with design consideration rather than actual code at the moment as WPF is confusing matters for me.

Currently, I'm verging towards using a single instance of System.Diagnostics.Stopwatch and allow each panel to act on the stopwatch event whether the interval time has been reached.

Can anyone advise?

Thank you O

Upvotes: 1

Views: 2500

Answers (4)

S3ddi9
S3ddi9

Reputation: 2151

use can inherit from DocumentPanel if you need the Tag property & for more encapsulation

    class UpdatableDocumentPanel : DocumentPanel
    {
        public int myinterval { get; set; }//the individual update interval (300ms for example)
        int currentinterval;


        public void Update()
        {

            currentinterval++;

            if (myinterval == currentinterval)
            {
                currentinterval = 0;
                UpdateMyPanelMethod();
            }
        }
    }

and

 .... Form_Loaded....
 {
  .....
  mypanel.myinterval = 2; // 2 * 100ms
  .....
 }

 .... Timer_Tick....
 {
    ....
   mypanel.Update(); // simply
    ....
 }

Upvotes: 0

wdavo
wdavo

Reputation: 5110

I've used the following approach to achieve something similar in a Silverlight app:

Single timer which ticks at a small interval (you're discretion, but would need to be lower than the lowest supported update interval), and then have each DocumentPanel subscribe to this timer's tick event.

When the tick event is fired, each DocumentPanel would then determine if an update is required based on it's update frequency (E.G. (last update - now ) > interval).

There's a comparison of some timer classes here:

http://msdn.microsoft.com/en-us/magazine/cc164015.aspx

DispatcherTimer isn't mentioned, but the important difference between DispatcherTimer and System.Timers.Timer is:

If a System.Timers.Timer is used in a WPF application, it is worth noting that the System.Timers.Timer runs on a different thread then the user interface (UI) thread. In order to access objects on the user interface (UI) thread, it is necessary to post the operation onto the Dispatcher of the user interface (UI) thread using Invoke or BeginInvoke. Reasons for using a DispatcherTimer opposed to a System.Timers.Timer are that the DispatcherTimer runs on the same thread as the Dispatcher and a DispatcherPriority can be set on the DispatcherTimer.

(from http://msdn.microsoft.com/en-us/library/system.windows.threading.dispatchertimer.aspx).

Without knowing how you are currently handling UI updates and how you're program is structured, it's hard to say which timer you should use.

I'm not hugely familiar with the using the StopWatch, but my opinion is (after reading http://msdn.microsoft.com/en-us/library/system.diagnostics.stopwatch.aspx) that using a single StopWatch isn't something that is particularly suited to this problem

Upvotes: 1

MikeKulls
MikeKulls

Reputation: 3049

Generally in a case like this I would have a single timer which when then check for the elapsed time for each DocumentPanel. I'm guessing 100% accuracy is not critical, if they select 999ms then they won't notice if you main timer fires every 50ms so can only give them increments of 50ms. Windows does not give that sort of accuracy anyway, I learnt this when trying to trigger a flash once.

Upvotes: 1

S3ddi9
S3ddi9

Reputation: 2151

its better to use just one System.Windows.Threading.DispatcherTimer with 100ms as ticks, then use Tags to determine its own interval, for example you can use

struct IntervalComparer
{
     int myinterval; //the individual update interval (300ms for example)
     int currentinterval;
     public IntervalComparer(int myinterval)
    {
            this.myinterval=myinterval;
            this.currentinterval=0;
    }

        public void TickMe()
        {
            currentinterval++;
        }

        public void ResetkMe()
        {
            currentinterval = 0;
        }

        public bool CanIUpdate()
        {
            return myinterval == currentinterval;
        }
}

on the creation

.... Form_Loaded....
{
 .....
      mypanel=new Panel();
      mypanel.Tag= new IntervalComparer(2); // 2 * 100ms
 .....
}

.... Timer_Tick....
{
   ....
   (mypanel.Tag as IntervalComparer).TickMe();
    if((mypanel.Tag as IntervalComparer).CanIUpdate())
     {
       UpdateMyPanel();//your update method 
       (mypanel.Tag as IntervalComparer).ResetMe();
     }

   ....
}

Upvotes: 1

Related Questions