Not sure how to handle multiple timed threads in a Windows service - multithreading

This is my first time putting together a Windows service application and I've been doing a bit of reading on different approaches to running multiple tasks in some manner of timed intervals. One being once a day and another every 1 min.
What I had concluded to do was use the TimedCallBack and System.threating.timer timer.
Non-elegant example
private void DailyTask(object state) {
//do something daily
}
private void IntervalTask(object state) {
//do something else
}
private void OnStart() {
TimedCallBack dailyTcb = DailyTask;
TimedCallBack intervalTcb = IntervalTask;
System.Threading.Timer dailyTimer = new Timer(dailyTcb, null, 0, 86400000);
System.Threading.Timer intervalTimer = new Timer(intervalTcb, null, 0, 60000);
}
private void OnStop() {
intervalTimer.Dispose();
dailyTimer.Dispose();
}
Questions
1) does the timer start the clock following the completion of the task? Which would slowly cause it to creep past a day if every time it ran it took some amount of time to complete? Which I would assume then that I would need to determine how long it took to
run minus 24hrs?
2) is this a perfectly fine approach for 2 simple tasks.
Thanks

The timer does not wait until after completion of the task to restart the timer. For example, if you set your timer to 20 milliseconds and the callback took more than 20 milliseconds to process, you would get another tick before the first one finished.
I don't see anything particularly wrong with your idea. However, if that's all your service is doing (i.e. just sitting there, waiting to fire once per interval), you might consider making it a simple console mode program and using scheduled tasks to execute it. Check out Windows Task Scheduler and the schtasks command line tool.

Related

.NET - Multiple Timers instances mean Multiple Threads?

I already have a windows service running with a System.Timers.Timer that do a specific work. But, I want some works to run at the same time, but in different threads.
I've been told to create a different System.Timers.Timer instance. Is this correct? Is this way works running in parallel?
for instance:
System.Timers.Timer tmr1 = new System.Timers.Timer();
tmr1.Elapsed += new ElapsedEventHandler(DoWork1);
tmr1.Interval = 5000;
System.Timers.Timer tmr2 = new System.Timers.Timer();
tmr2.Elapsed += new ElapsedEventHandler(DoWork2);
tmr2.Interval = 5000;
Will tmr1 and tmr2 run on different threads so that DoWork1 and DoWork2 can run at the same time, i.e., concurrently?
Thanks!
It is not incorrect.
Be careful. System.Timers.Timer will start a new thread for every Elapsed event. You'll get in trouble when your Elapsed event handler takes too long. Your handler will be called again on another thread, even though the previous call wasn't completed yet. This tends to produce hard to diagnose bugs. Something you can avoid by setting the AutoReset property to false. Also be sure to use try/catch in your event handler, exceptions are swallowed without diagnostic.
Multiple timers might mean multiple threads. If two timer ticks occur at the same time (i.e. one is running and another fires), those two timer callbacks will execute on separate threads, neither of which will be the main thread.
It's important to note, though, that the timers themselves don't "run" on a thread at all. The only time a thread is involved is when the timer's tick or elapsed event fires.
On another note, I strongly discourage you from using System.Timers.Timer. The timer's elapsed event squashes exceptions, meaning that if an exception escapes your event handler, you'll never know it. It's a bug hider. You should use System.Threading.Timer instead. System.Timers.Timer is just a wrapper around System.Threading.Timer, so you get the same timer functionality without the bug hiding.
See Swallowing exceptions is hiding bugs for more info.
Will tmr1 and tmr2 run on different threads so that DoWork1 and DoWork2 can run at the same time, i.e., concurrently?
At the start, yes. However, what is the guarantee both DoWork1 and DoWork2 would finish within 5 seconds? Perhaps you know the code inside DoWorkX and assume that they will finish within 5 second interval, but it may happen that system is under load one of the items takes more than 5 seconds. This will break your assumption that both DoWorkX would start at the same time in the subsequent ticks. In that case even though your subsequent start times would be in sync, there is a danger of overlapping current work execution with work execution which is still running from the last tick.
If you disable/enable respective timers inside DoWorkX, however, your start times will go out of sync from each other - ultimately possible they could get scheduled over the same thread one after other. So, if you are OK with - subsequent start times may not be in sync - then my answer ends here.
If not, this is something you can attempt:
static void Main(string[] args)
{
var t = new System.Timers.Timer();
t.Interval = TimeSpan.FromSeconds(5).TotalMilliseconds;
t.Elapsed += (sender, evtArgs) =>
{
var timer = (System.Timers.Timer)sender;
timer.Enabled = false; //disable till work done
// attempt concurrent execution
Task work1 = Task.Factory.StartNew(() => DoWork1());
Task work2 = Task.Factory.StartNew(() => DoWork2());
Task.Factory.ContinueWhenAll(new[]{work1, work2},
_ => timer.Enabled = true); // re-enable the timer for next iteration
};
t.Enabled = true;
Console.ReadLine();
}
Kind of. First, check out the MSDN page for System.Timers.Timer: http://msdn.microsoft.com/en-us/library/system.timers.timer.aspx
The section you need to be concerned with is quoted below:
If the SynchronizingObject property is null, the Elapsed event is
raised on a ThreadPool thread. If processing of the Elapsed event
lasts longer than Interval, the event might be raised again on another
ThreadPool thread. In this situation, the event handler should be
reentrant.
Basically, this means that where the Timer's action gets run is not such that each Timer has its own thread, but rather that by default, it uses the system ThreadPool to run the actions.
If you want things to run at the same time (kick off all at the same time) but run concurrently, you can not just put multiple events on the elapsed event. For example, I tried this in VS2012:
static void testMethod(string[] args)
{
System.Timers.Timer mytimer = new System.Timers.Timer();
mytimer.AutoReset = false;
mytimer.Interval = 3000;
mytimer.Elapsed += (x, y) => {
Console.WriteLine("First lambda. Sleeping 3 seconds");
System.Threading.Thread.Sleep(3000);
Console.WriteLine("After sleep");
};
mytimer.Elapsed += (x, y) => { Console.WriteLine("second lambda"); };
mytimer.Start();
Console.WriteLine("Press any key to go to end of method");
Console.ReadKey();
}
The output was this:
Press any key to go to end of method
First lambda.
Sleeping 3 seconds
After sleep
second lambda
So it executes them consecutively not concurrently. So if you want "a bunch of things to happen" upon each timer execution, you have to launch a bunch of tasks (or queue up the ThreadPool with Actions) in your Elapsed handler. It may multi-thread them, or it may not, but in my simple example, it did not.
Try my code yourself, it's quite simple to illustrate what's happening.

Why worker thread transitions from CANCELLED to SCHEDULED skipping READY? (JavaFX2)

Update: I am finding the problem with other threads too; they enter Scheduled state but never transition to Running. why?
My program has a Service that uses a Task to connect to a device through the serial port.
In other words,
public class ConnectService extends Service<String> {
protected Task createTask() {
return new ConnectTask();
}
class ConnectTask extends Task<ObservableList<String>> {
#Override
protected ObservableList<String> call() throws Exception {
...
connect();
...
}
}
}
If a previous call to connect to the device got hung, then I want to cancel the task/thread and start over afresh in this attempt.
In order to do this,
if (connectService.getState() != Worker.State.READY) {
connectService.cancel();
}
connectService.restart();
However in the debugger I am finding that if the state is SCHEDULED, then the above code sends it to CANCELLED. But restart() will not send it to READY - instead it goes back to SCHEDULED - and call() does not get executed!
This seems to contradict the docs here
A reusable Worker will transition from CANCELLED, SUCCEEDED or FAILED
back to READY.
I tried
if (connectService.getState() != Worker.State.READY) {
connectService.cancel();
connectService.reset();
}
connectService.start();
Now state goes back to READY, but call() is never executed!
You need to add Worker.State.SCHEDULED to the states excluded from your if condition, i.e.
if (connectService.getState() != Worker.State.READY &&
connectService.getState() != Worker.State.SCHEDULED) {
connectService.cancel();
}
connectService.restart();
This is because the Worker will always transition from READY to SCHEDULED before it enters the RUNNING state. From the docs
However even in cases where the Worker is executed immediately, the
Worker will temporarily enter the SCHEDULED state before entering the
RUNNING state. That is, the transition is always from READY to
SCHEDULED to RUNNING (unless of course the Worker in cancelled).
If for some reason your working is stuck in the SCHEDULED state, it's likely that the cancel and restart just returns it to the same stuck state.
Also, (not seeing the rest of your code, so this is just extrapolation) the idea of interrupting it when you catch it running on the assumption that it is hung seems shaky, since it could be working well but taking longer than expected, or it could be hanging every time you call it. If there's no test you can run within connectService to determine whether it's hung or not, then I guess you're stuck with something like this, but it feels problematic.

Correct Usage Of System.Threading.Timer

I stumbled across some code similar to below:
private void SomeCallBack(object state)
{
lock (_lock)
{
try
{
if (_timer == null)
return;
_timer.Dispose();
// do some work here
}
catch
{
// handle exception
}
finally
{
_timer = new Timer(SomeCallBack, state, 100, Timeout.Infinite);
}
}
}
I don't understand the purpose of recreating the timer every time the callback is executed. I think what the code is trying to achieve is that only one thread can perform the work at a time. But wouldn't the lock be sufficient?
Also, according to msdn,
Note that callbacks can occur after the Dispose() method overload has been called
Is there any benefits of doing this?
If so, do the benefits justify the overheads in disposing and creating the timer?
Thanks for your help.
It seems that the code wants a nearly periodic timer (not exactly periodic because of the jitter introduced by the processing between the expiration of the timer and creation of the new timer). Disposing and recreating the timer is indeed an unnecessary overhead. The Change method would be better.
The check for null is also curious; somewhere else there would have to be code that sets _timer null for it to have any effect.
The reason for recreating the timer would be for the scenario where the code in the timer callback takes longer to execute than the timer period. In this case multiple instances of the callback would be running at the same time.

How does cron internally schedule jobs?

How do "modern" cron daemons internally schedule their jobs? Some cronds used to schedule a run every so often via at. So after a crontab is written out, does crond:
Parse the crontab for all future events and the sleep for the intervals?
Poll an aggregated crontab database every minute to determine if the current time matches the schedule pattern?
Other?
Thanks,
A few crickets heard in this question. Good 'ol RTFC with some discrete event simulation papers and Wikipedia:
http://en.wikipedia.org/wiki/Cron#Multi-user_capability
The algorithm used by this cron is as
follows:
On start-up, look for a file named .crontab in the home directories of
all account holders.
For each crontab file found, determine the next time in the future
that each command is to be run.
Place those commands on the Franta-Maly event list with their
corresponding time and their "five
field" time specifier.
Enter main loop:
Examine the task entry at the head of the queue, compute how far in the
future it is to be run.
Sleep for that period of time.
On awakening and after verifying the correct time, execute the task at
the head of the queue (in background)
with the privileges of the user who
created it.
Determine the next time in the future to run this command and place
it back on the event list at that time
I wrote a blog post describing it.
Quoting the relevant text from there:
We can have a finite thread-pool which will execute all the tasks by picking them up from a PriorityBlockingQueue (thread-safe heap) prioritized on job.nextExecutionTime().
Meaning that the top element of this heap will be always be the one that will fire the soonest.
We will be following the standard threadpool producer-consumer pattern.
We will have one thread which will be running in an infinite loop and submitting new jobs to the thread pool after consuming them from the queue.
Lets call it QueueConsumerThread:
void goToSleep(job, jobQueue){
jobQueue.push(job);
sleep(job.nextExecutionTime() - getCurrentTime());
}
void executeJob(job, jobQueue){
threadpool.submit(job); // async call
if (job.isRecurring()) {
job = job.copy().setNextExecutionTime(getCurrentTime() + job.getRecurringInterval());
jobQueue.add(job);
}
}
#Override
void run(){
while(true)
{
job = jobQueue.pop()
if(job.nextExecutionTime() > getCurrentTime()){
// Nothing to do
goToSleep(job, jobQueue)
}
else{
executeJob(job, jobQueue)
}
}
}
There will be one more thread which will be monitoring the crontab file for any new job additions and will push them to the queue.
Lets call it QueueProducerThread:
#Override
void run()
{
while(true)
{
newJob = getNewJobFromCrontabFile() // blocking call
jobQueue.push(newJob)
}
}
However, there is a problem with this:
Imagine that Thread1 is sleeping and will wake up after an hour.
Meanwhile a new task arrives which is supposed to run every minute.
This new task will not be able to start executing until an hour later.
To solve this problem, we can have ProducerThread wakeup ConsumerThread from its sleep forcefully whenever the new task has to run sooner than the front task in the queue:
#Override
void run()
{
while(true)
{
newJob = getNewJobFromCrontabFile() // blocking call
jobQueue.push(newJob)
if(newJob == jobQueue.peek())
{
// The new job is the one that will be scheduled next.
// So wakeup consumer thread so that it does not oversleep.
consumerThread.interrupt()
}
}
}
Note that this might not be how cron is implemented internally.
However, this is the most optimal solution that I can think of.
It requires no polling and all threads sleep until they need to do any work.

How to specify a timeout value on HttpWebRequest.BeginGetResponse without blocking the thread

I’m trying to issue web requests asynchronously. I have my code working fine except for one thing: There doesn’t seem to be a built-in way to specify a timeout on BeginGetResponse. The MSDN example clearly show a working example but the downside to it is they all end up with a
SomeObject.WaitOne()
Which again clearly states it blocks the thread. I will be in a high load environment and can’t have blocking but I also need to timeout a request if it takes more than 2 seconds. Short of creating and managing a separate thread pool, is there something already present in the framework that can help me?
Starting examples:
http://msdn.microsoft.com/en-us/library/ms227433(VS.100).aspx
http://msdn.microsoft.com/en-us/library/system.net.httpwebrequest.begingetresponse.aspx
What I would like is a way for the async callback on BeginGetResponse() to be invoked after my timeout parameter expires, with some indication that a timeout occurred.
The seemingly obvious TimeOut parameter is not honored on async calls.
The ReadWriteTimeout parameter doesn't come into play until the response returns.
A non-proprietary solution would be preferable.
EDIT:
Here's what I came up with: after calling BeginGetResponse, I create a Timer with my duration and that's the end of the "begin" phase of processing. Now either the request will complete and my "end" phase will be called OR the timeout period will expire.
To detect the race and have a single winner I call increment a "completed" counter in a thread-safe manner. If "timeout" is the 1st event to come back, I abort the request and stop the timer. In this situation, when "end" is called the EndGetResponse throws an error. If the "end" phase happens first, it increments the counter and the "timeout" foregoes aborting the request.
This seems to work like I want while also providing a configurable timeout. The downside is the extra timer object and the callbacks which I make no effort to avoid. I see 1-3 threads processing various portions (begin, timed out, end) so it seems like this working. And I don't have any "wait" calls.
Have I missed too much sleep or have I found a way to service my requests without blocking?
int completed = 0;
this.Request.BeginGetResponse(GotResponse, this.Request);
this.timer = new Timer(Timedout, this, TimeOutDuration, Timeout.Infinite);
private void Timedout(object state)
{
if (Interlocked.Increment(ref completed) == 1)
{
this.Request.Abort();
}
this.timer.Change(Timeout.Infinite, Timeout.Infinite);
this.timer.Dispose();
}
private void GotRecentSearches(IAsyncResult result)
{
Interlocked.Increment(ref completed);
}
You can to use a BackgroundWorker to run your HttpWebRequest into a separated thread, so your main thread still alive. So, this background thread will be blocked, but first one don't.
In this context, you can to use a ManualResetEvent.WaitOne() just like in that sample: HttpWebRequest.BeginGetResponse() method.
What kind of an application is this? Is this a service proces/ web application/console app?
How are you creating your work load (i.e requests)? If you have a queue of work that needs to be done, you can start off 'N' number of async requests (with the framework for timeouts that you have built) and then, once each request completes (either with timeout or success) you can grab the next request from the queue.
This will thus become a Producer/consumer pattern.
So, if you configure your application to have a maximum of "N' requests outstanding, you can maintain a pool of 'N' timers that you reuse (without disposing) between the requests.
Or, alternately, you can use ThreadPool.SetTimerQueueTimer() to manage your timers. The threadpool will manage the timers for you and reuse the timer between requests.
Hope this helps.
Seems like my original approach is the best thing available.
If you can user async/await then
private async Task<WebResponse> getResponseAsync(HttpWebRequest request)
{
var responseTask = Task.Factory.FromAsync(request.BeginGetResponse, ar => (HttpWebResponse)request.EndGetResponse(ar), null);
var winner = await (Task.WhenAny(responseTask, Task.Delay(new TimeSpan(0, 0, 20))));
if (winner != responseTask)
{
throw new TimeoutException();
}
return await responseTask;
}

Resources