System threading Timer vs Scheduler - c#

I am using Microsoft Graph to get notifications for new emails, and I have to subscribe to the webhook, challenge is the subscription lasts for only 3 days so I have to constantly renew the subscription.
What is the best way to do it? Right now I can see two choices to use a timer or an scheduler, timer looks like and overhead to the application and not that much reliable.
I have not used Timers in any production applications yet, so I am not very much sure about them.

Web applications that are inactive in IIS can be flushed by the server. That means that a system threading started from the main web thread would not guarantee you that it runs at the right time or at all if your application does not have a lot of activity. A timer job would guarantee that the job runs on time as long as the machine is online and in an healthy state

Related

Send heartbeat in long running hangfire process

Is it possible to send a heartbeat to hangfire (Redis Storage) to tell the system that the process is still alive? At the moment I set the InvisibilityTimeout to TimeSpan.MaxValue to prevent hangfire from restarting the job. But, if the process fails or the server restarts, the job will never be removed from the list of running jobs. So my idea was, to remove the large time out and send a kind of heartbeat instead. Is this possible?
I found https://discuss.hangfire.io/t/hangfire-long-job-stop-and-restart-several-time/4282/2 which deals with how to keep a long-running job alive in Hangfire.
The User zLanger says that jobs are considered dead and restarted once you ...
[...] are hitting hangfire’s invisibilityTimeout. You have two options.
increase the timeout to more than the job will ever take to run
have the job send a heartbeat to let hangfire’s know it’s still alive.
That's not new to you. But interestingly, the follow-up question there is:
How do you implement heartbeat on job?
This remains unanswered there, a hint that that your problem is really not trivial.
I have never handled long-running jobs in Hangfire, but I know the problem from other queuing systems like the former SunGrid Engine which is how I got interested in your question.
Back in the days, I had exactly your problem with SunGrid and the department's computer guru told me that one should at any cost avoid long-running jobs according to some mathematical queuing theory (I will try to contact him and find the reference to the book he quoted). His idea is maybe worth sharing with you:
If you have some job which takes longer than the tolerated maximal running time of the queuing system, do not submit the job itself, but rather multiple calls of a wrapper script which is able to (1) start, (2) freeze-stop, (3) unfreeze-continue the actual task.
This stop-continue can indeed be a suspend (CTRL+Z respectively fg in Linux) on operating-system level, see e.g. unix.stackexchange.com on that issue.
In practice, I had the binary myMonteCarloExperiment.x and the wrapper-script myMCjobStarter.sh. The maximum compute time I had was a day. I would fill the queue with hundreds of calls of the wrapper-script with the boundary condition that only one at a time of them should be running. The script would check whether there is already a process myMonteCarloExperiment.x started anywhere on the compute cluster, if not, it would start an instance. In case there was a suspended process, the wrapper script would forward it and let it run for 23 hours and 55 minutes, and suspend the process then. In any other case, the wrapper script would report an error.
This approach does not implement a job heartbeat, but it does indeed run a lengthy job. It also keeps the queue administrator happy by avoiding that job logs of Hangfire have to be cleaned up.
Further references
How to prevent a Hangfire recurring job from restarting after 30 minutes of continuous execution seems to be a good read

Is it bad practice to let ServiceController class running 24/7?

I have multiple windows services which run 24/7 on a server. For logging events etc. I already use log4net but I want to be able to see if all my services are still running. So I've stumbled upon this question and learned about the ServiceController class. Now I've had the idea to make another service in which I create a ServiceController object per service, and use the WaitForStatus method to be notified when any of the services are stopped. I'd be able to check for any statuses externally through a hosted WCF in the servicecontroller service.
But I've also seen the answer to this question which states a ServiceController should be closed and disposed. Would it be bad to let my ServiceController wait 24/7 until any of my services stopped? Or should I use Quartz or a simple Timer to run a check every x amount of time?
Thanks in advance
You shouldn't. There is no mechanism in Windows to let a service status change generate an event. So ServiceController.WaitForStatus() must poll. It is hard-coded to query the service status 4 times per second, a Thread.Sleep(250) hard-codes the poll interval. Use a decompiler to see this for yourself.
So you basically have many threads in your program, doing nothing but sleep for hours. That's pretty ugly, a thread is an expensive OS object. These threads don't burn any core but the OS thread scheduler is still involved, constantly re-activating the threads when their sleep period expires.
If you need this kind of responsiveness to status changes then it is okayish, but keep in mind that it cannot be more responsive than 250 msec. And keep in mind that increasing the interval by using a Timer sounds attractive but do consider the problem with polling. If you do it, say, once a minute and an admin stops and restarts the service in, say, 30 seconds between two polls then you'll never see the status change. Oops.
Consider to use only one thread that queries many ServiceControllers through their Status property. Your own polling code, minus the cost of the threads.

Queue a Windows service if already running

I'm developing a Windows Service that will run every 15 minutes, and sends out push notifications to iOS, Android, and BlackBerry users. Each of these device specific operations will run in separate threads in the Windows service. That's all well and good, but there is a chance that we will need to send out up to 50,000 push notifications at a time. If this happens, it could possibly take more than 15 minutes, so before it's time for the next service to run, I want to know if the previous process has finished, and if it hasn't, wait and queue the Windows service to execute once the prior execution is complete. I'm fine with the threading aspect, but I don't know the correct way to implement the scenario that I've described above. Is there some sort of "Wait" or "Queue" mechanism in C#?
Since your service is using a Timer to schedule the work, it can always disable the timer when work begins, and reschedule, as needed, at the end of your work.
This allows a lot of flexibility. If a queue of work took more than 15 minutes, you could decide whether to delay the next one, just start it immediately (potentially running "forever"), skip it entirely, or whatever you needed, as the timer won't run again until it was reenabled.

Timer, app pool timeout

I have a timer running in my web application. Each time the application starts up, the timer is created. The issue is that the app pool ends after an idle period which also ends the timer. The next request causes the app pool to start back up and a new timer is created.
Is there anyway to keep the timer from resetting?
This is a question I see a lot. The short answer is no, the long answer is that even if you would periodically poll the web site it will eventually recycle the app pool anyway.
If need to do background work like this and embed that in ASP.NET you have to create a robust work queue that doesn't break if there are interruptions or crashes because it's going to happen. And that's just good design anyway for long running processes. This might seem like a lot of work but a simple design can take you very far.
The recommended approach is to pull that code into a separate Win32 service because the nature of such workloads don't sit well in REST based architectures.
If all you need is a periodic check, then it might be fine with just having an external script polling the web site but it's a crude way of handling timers.

ASP.NET Mvc: How to trigger a notification event after a date?

I'm trying to build a planner web app using ASP.NET MVC 3.
One of the problem I don't know is how to automatically trigger an event(send mail whatever) when the time is one that spot?
Who can help? Thanks.
In addition to your front end asp.net site that allows configuration of events, you will need a backend service attached to the database that sends out the notifications. This back end service should keep track of the last time it processed events. It will wake up periodically and process all newer events. The period will be determined by how 'real time' you want your responses. Once every minute is probably as fine grain as you may need.
Personally I would not make the web app handle that. Instead, I'd have a service that runs in the background or use the Windows Schedule to run certain application every x min/hour.
But with ASP.NET, you could start a background thread that calls some function every x time.
Here's more on that: http://flimflan.com/blog/SafelyRunningBackgroundThreadsInASPNET20.aspx
I hope this helps you in the right direction.
Timed events can be handled with threads or a service.
The downside to threads and timers that's not often considered is that often IIS will restart, which will restart your threads and timers. A service is much more stable and will fire automatically every so often without requiring you to keep track of state data (such as the current time).
A service or a scheduled task is the best fit for this problem, but if your hosting provider (assuming you aren't self-hosting) does not allow for this, or they want a lot more money for this ability, then an alternative you can consider,if running in .NET 4.0, it always having the application pool stay alive.
This blog post by Scott Guthrie describes how this can be done:
http://weblogs.asp.net/scottgu/archive/2009/09/15/auto-start-asp-net-applications-vs-2010-and-net-4-0-series.aspx

Categories