I want a timer tick/elapsed event inside a new thread. It seems like I cannot use the Windows timer. But if I use the Timers.Timer, it creates worked thread from the threadpool for each elapsed event. Is there a way to make these events to occur in the same thread?
Update:
Thank you everybody for answering this question.
My intention behind the whole thing might sound a little crazy though. I want you to correct me. This is my thinking(as a novice) when I am trying to acieve this. I am trying perform a task every 2 seconds. When I use Timers.Timer, it creates a thread every 2 seconds which I am thinking it as an overhead.
My main thread and my other threads need a lot of processor’s time to perform their tasks. So, if I can avoid creating these Threads, I am saving whatever microseconds of the processor to create a thread each time timer elapsed, for my main and other threads.
I made a quick tests and compared few solutions. 1000 msec interval in each case. 100 ticks.
Solution1: infinite loop with waits/sleep {00:01:42.0068344}
solution2: Using Brian’s Synchronizer {00:01:42.4068573}
solution3: Timers.Timer as it is {00:01:42.4018571}
This should tell me that 2.0068344, 2.4068573, 2.4018571 are the times wasted for other things in the background other than the time interval of 1000 msec for 100 ticks. This should mean when solution1 meet your needs, it is the best solution performance-wise??
This should also mean that though Brian’s solution is synchronized to one thread, it is in-fact creating threads in the background.
Please confirm it or correct me.
Yes. You can make the
System.Timers.Timerexecute theElapsedevent handler in the same thread. To do this you need to set theSynchronizingObjectproperty to an object that will marshal the execution onto a thread of your choosing. However, it is important to realize that you cannot just inject execution onto a random thread. The receiving thread has to be specifically designed to allow marshaling the execution of method calls.And here is the code for the
Synchronizerclass. This code uses the BlockingCollection class from 4.0 of the .NET BCL. If you are not using 4.0 then you can replace it with Stephen Toub’s BlockingQueue.Update:
You need to understand how
System.Timers.Timerworks. It actually usesSystem.Threading.Timerbehind the scenes and executes the event handler on aThreadPoolthread. So it is not really creating any threads at all. The same ones from the thread pool are getting recycled over and over again. There is no thread creation overhead. That is the whole point of a thread pool.Now, the solution I provided here still uses the
ThreadPoolbehind the scenes, but instead of having the work item execute theElapsedevent handler directly it is executing theSynchronizer.BeginInvokemethod which marshals the event handler onto the thread that theSynchronizercreated.So it should be no surpise that the solution I provided here would be slower. Personally, I would stick to solution #1 as it is easier. I would not worry a whole lot about performance at this point.