1

I'm new to C# and I'm doing a project needs two timer to access the same variable at the same time.(one to read and other one to write or update).So, my problem is which Timer should I use? Forms.Timer or Thread.Timer. I've read some article about their difference. Since I want to use these timers to update the Interface of the program (image in picture box), So I think Forms.Timer should be used here since it's related to GUI stuff. However, the order that which timer executes first is also matter, so I think Thread.Timer should also be considered. Is there any way I can combine them together?

Update: I'm doing a ECG project, so basically I'm keeping receiving data and I want to draw them on the form. however, since drawing took about 40 ms, so using one timer would have delay but I need real time.(For example, If I set the interval to 100 ms, then It took 140 ms to finish one frame drawing that should be finished in 100 ms. This will cause 40 ms delay for every tick. ) Therefore, My solution is using one timer to update the data buffer when I received the data, and use other timer to call Invalidate, which would repaint all the new data. Should I use thread.timer to do the updating of data and form.timer to redraw the form?

  • What do you mean "the order that which timer executes first is also matter?" Do you expect the two timers to fire at exactly the same time, and need to handle events in a certain order? – John Wu Dec 14 '19 at 00:07
  • 1
    You should stick with the WinForms specific timer. You won't have to deal with controlling access to your variables via locks that way. – Bradley Uffner Dec 14 '19 at 00:12
  • What exactly is your program doing? It sounds like there may be a better pattern for this. – Rufus L Dec 14 '19 at 00:47
  • @Rufus L, Hi I just edit my question, could you provide me any advice or better solution – oocharlesxx Dec 14 '19 at 01:05
  • @JohnWu, I want both timer to execute at the same time, one timer drawing the data, and other one update it. So they don't have to wait until each other finish. I know forms.timer would have an spread thread other than Main thread, but what If I use two forms.timer, are they ruining on the same thread? – oocharlesxx Dec 14 '19 at 01:09
  • @oocharlesxx I'd not recommend to use timers at all. There is [Rx.NET](https://github.com/dotnet/reactive) which allows you to do what you need in a couple of lines. If you work with even emitter and need to make a processor feel free to use existing freamworks, you'll benefit from them a lot in many aspects (maintainability/testability/modifyability etc). Will post an answer with a solution tonight. – fenixil Dec 14 '19 at 01:27
  • @oocharlesxx can you please provide more details how you do receive data? is it sync or asycn, pull or push (do you call method and get result or you subscribe to some event)? – fenixil Dec 14 '19 at 01:30
  • @fenixil, Hi, I just made an http request every 5 second and store the data in the buffer(an byte array). – oocharlesxx Dec 14 '19 at 02:03
  • Add an event to your receiver proc. Raise the event when you receive new data, passing it through in a custom EventArgs class. Subscribe to the Event in your Form, then `Invalidate()` the control used as canvas to draw the new *data*. – Jimi Dec 14 '19 at 19:05
  • 1
    Adding to what @Jimi said. The trick to getting this running smoothly is doing the drawing in a Paint handler and then carefully managing Invalidation regions. Process the incoming data when it arrives and then invalidate just the area that needs updating. Some time later, your Paint routine will be called upon. Only the Invalidated region will be updated – Flydog57 Dec 14 '19 at 23:44

1 Answers1

2

The main difference between both timers is that the Form.Timer works in the same thread as your Form, so there is no problem in accessing or changing state of any GUI component (control etc.) by Tick event handler code. In case of Thread.Timer, there is no guarantee that the TimerCallback method is called from current thread (can be, but not must be), so accessing the GUI components can be slightly hard and not easy (you have to use Invoke(), like here: Accessing a form's control from a separate thread). On the other hand, any long-term and intensive processing, implemented in Form.Timer.Tick handler will be executed in same thread as GUI, so it can degrade GUI efficiency and responsibility. So, the general rule is: for fast, short-term operations on GUI components, use Form.Timer, and for long-term, heavy computations, not requiring access to GUI components, use Thread.Timer. Of course, it is simplified rule - the final decision should depend to specific case.

VillageTech
  • 1,968
  • 8
  • 18
  • 1
    so, I should use thread.Timer to update the data buffer since it need more computation, and form.Timer to repaint the form right? One more question is are they running on the same thread? – oocharlesxx Dec 14 '19 at 01:18
  • Right. About running thread, as I wrote: the `Form.Timer.Tick` event handler will work on the GUI thread, and the `Thread.Timer.TimerCallback` mainly and usually works on different thread than GUI. – VillageTech Dec 14 '19 at 01:21