I have a C# program that needs to dispatch a thread every X minutes, but only if the previously dispatched thread (from X minutes) ago is not currently still running.
A plain old Timer
alone will not work (because it dispatches an event every X minutes regardless or whether or not the previously dispatched process has finished yet).
The process that's going to get dispatched varies wildly in the time it takes to perform it's task - sometimes it might take a second, sometimes it might take several hours. I don't want to start the process again if it's still processing from the last time it was started.
Can anyone provide some working C# sample code?
You can use System.Threading.Timer. Trick is to set the initial time only. Initial time is set again when previous interval is finished or when job is finished (this will happen when job is taking longer then the interval). Here is the sample code.
Why not use a timer with
Monitor.TryEnter()
? IfOnTimerElapsed()
is called again before the previous thread finishes, it will just be discarded and another attempt won't happen again until the timer fires again.You can disable and enable your timer in its elapsed callback.
You can just use the
System.Threading.Timer
and just set theTimeout
toInfinite
before you process your data/method, then when it completes restart theTimer
ready for the next call.If I understand you correctly, you actually just want to ensure your thread is not running before you dispatch another thread. Let's say you have a thread defined in your class like so.
You can do:
then add the callBack like so
Using the PeriodicTaskFactory from my post here
The output below shows that even though the interval is set 1000 milliseconds, each iteration doesn't start until the work of the task action is complete. This is accomplished using the
synchronous: true
optional parameter.UPDATE
If you want the "skipped event" behavior with the PeriodicTaskFactory simply don't use the synchronous option and implement the Monitor.TryEnter like what Bob did here https://stackoverflow.com/a/18665948/222434
The nice thing about the
PeriodicTaskFactory
is that a Task is returned that can be used with all the TPL API, e.g.Task.Wait
, continuations, etc.