简体   繁体   中英

c# - Execute multiple threads on timer tick

I got a program that has a Timer that ticks every second and on every tick I need to execute a methods multiple times. I would like to make each method call in its own thread. The method I'm calling does a lot of work and ends with a webservice call so it can take some time to complete (0-30 seconds). I don't need to collect the response so its basically fire and forget.

The problem is if the method needs to be called eg 5 times per second it'll only be called 1-2 times, its like the rest is ignored because a new timer tick will fire.

I'm using .net 3.5, winforms and ThreadPool.QueueUserWorkItem

Any idea how I can make sure that all method calls are being executed on each timer tick ?

I can post source code if needed.

Thanks

The main problem in multithreading environment is that you don't have any guarantee that the work item that you've started, will execute in that exactly time you've started.

There are a lot of causes some thread will freeze: a new thread with higher priority, CPU bug, exception and so on and so on. So even if you start your work with ThreadPool.QueueUserWorkItem there is no guarantee that the ThreadPool will execute it right in that way.

First of all, take a note that the ThreadPool.QueueUserWorkItem does not create a new thread each time. There is a huge possibility that the ThreadPool will wait for a existing thread to finish it's work, and use it again. By default, ThreadPool uses a number of internal threads equal to the numbers of cores on the machine - this approach minimizes the context switching among the threads.

Second, if you say that the work thread needs to be done is very long, and you create a 5 new requests each second, the user machine will very soon got the starvation problem - there will be a lot of work items to be executed with a fixed number of threads, and your application will die in context switching.

So my suggestion to you is to use the FIFO queue for a work items with storing the creation time and parameters you need to start the work item. So each second you'll add there a new data, and there will be a thread worker to fire the events according to this queue. But still there is no chances you'll got you code started right exactly the time you say to start it.

Maybe create an int called methodBacklog and when your timer ticks, increment it by 5 (or however many times you want to call your function).

Then your method should be triggered not when the tick happends, but when methodBacklog > 0. Then whenever you finish one method call (after the webservise) do methodBacklog-- (ie decrement methodBacklog by one).

That should make sure every single time you want it to be executed, will be executed :)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM