I have IIS server which runs few WCF REST services I created.
Now I need to add some kind of process that will run on the server and do some work for me once in a while.
I guess the IIS should initiate some kind of a background process or something, but I'm not sure what is the technology I should use in this case?
After reading at least three other similar questions, it appears the best practice is to avoid running background threads and allow a windows service app to do the processing. You could drop rows into a database table or append a line to a file to start the windows service work.
See any of these threads...
Can I use threads to carry out long-running jobs on IIS?
What are some best practices for managing background threads in IIS?
As an alternative to Windows Task Scheduler, as mentioned by others, you could also:
In your global.asax file, in your application_start() method, you can spin up a new Thread to do whatever you want, and shut it down in the application_end() method.
Check out the window task scheduler
You can schedule a process to come to life and then check to see if any component has queued up work for it to do. The work could be stored in a file (which would need to be locked) or a database table (that's my preference).
Windows Scheduled Tasks would typically be the way to do this.
Related
I need to execute an infinite while loop and want to initiate the execution in global.asax.
My question is how exactly should I do it? Should I start a new Thread or should I use Async and Task or anything else? Inside the while loop I need to do await TaskEx.Delay(5000);
How do I do this so it will not block any other processes and will not create memory leaks?
I use VS10,AsyncCTP3,MVC4
EDIT:
public void SignalRConnectionRecovery()
{
while (true)
{
Clients.SetConnectionTimeStamp(DateTime.UtcNow.ToString());
await TaskEx.Delay(5000);
}
}
All I need to do is to run this as a singleton instance globally as long as application is available.
EDIT:SOLVED
This is the final solution in Global.asax
protected void Application_Start()
{
Thread signalRConnectionRecovery = new Thread(SignalRConnectionRecovery);
signalRConnectionRecovery.IsBackground = true;
signalRConnectionRecovery.Start();
Application["SignalRConnectionRecovery"] = signalRConnectionRecovery;
}
protected void Application_End()
{
try
{
Thread signalRConnectionRecovery = (Thread)Application["SignalRConnectionRecovery"];
if (signalRConnectionRecovery != null && signalRConnectionRecovery.IsAlive)
{
signalRConnectionRecovery.Abort();
}
}
catch
{
///
}
}
I found this nice article about how to use async worker: http://www.dotnetfunda.com/articles/article613-background-processes-in-asp-net-web-applications.aspx
And this:
http://code.msdn.microsoft.com/CSASPNETBackgroundWorker-dda8d7b6
But I think for my needs this one will be perfect:
http://forums.asp.net/t/1433665.aspx/1
ASP.NET is not designed to handle this kind of requirement. If you need something to run constantly, you would be better off creating a windows service.
Update
ASP.NET is not designed for long running tasks. It's designed to respond quickly to HTTP requests. See Cyborgx37's answer or Can I use threads to carry out long-running jobs on IIS? for a few reasons why.
Update
Now that you finally mentioned you are working with SignalR, I see that you are trying to host SignalR within ASP.NET, correct? I think you're going about this the wrong way, see the example NuGet package referenced on the project wiki. This example uses an IAsyncHttpHandler to manage tasks.
You can start a thread in your global.asax, however it will only run till your asp.net process get recycled. This will happen at least once a day, or when no one uses of your site. If the process get recycled, the only way the thread is restarted agian, is when you have a hit on your site. So the thread is not running continueuosly.
To get a continues process it is better to start a windows service.
If you do the 'In process' solution, it realy depends on what your are doing. The Thread itself will not cause you any problems in memory or deadlocks. You should add a meganism to stop your thread when the application stops. Otherwise restarting will take a long time, because it will wait for your thread to stop.
This is an old post, but as I was seraching for this, I would like to report that in .NET 4.5.2 there is a native way to do it with QueueBackgroundWorkItem.
Take a look at this post: https://blogs.msdn.microsoft.com/webdev/2014/06/04/queuebackgroundworkitem-to-reliably-schedule-and-run-background-processes-in-asp-net/
MarianoC
It depends what you are trying to accomplish in your while loop, but in general this is the kind of situation where a Windows Service is the best answer. Installing a Windows Service is going to require that you have admin privileges on the web server.
With an infinite loop you end up with a lot of issues regard the Windows message pump. This is the thing that keeps a Windows application alive even when the application isn't "doing" anything. Without it, a program simply ends.
The problem with an infinite loop is that the application is stuck "doing" something, which prevents other applications (or threads) from "doing" their thing. There have been a few workarounds, such as the DoEvents in Windows Forms, but they all have some serious drawbacks when it comes to responsiveness and resource management. (Acceptable on a small LOB application, maybe not on a web server.) Even if the while-loop is on a separate thread, it will use up all available processing power.
Asynchronus programming is really designed more for long-running processes, such as waiting for a database to return a result or waiting for a printer to come online. In these cases, it's the external process that is taking a long time, not a while-loop.
If a Window Service is not possible, then I think your best bet is going to be setting up a separate thread with its own message pump, but it's a bit complicated. I've never done it on a web server, but you might be able to start an Application. This will provide a message pump for you and allow you to respond to Windows events, etc. The only problem is that this is going to start a Windows application (either WPF or WinForms), which may not be desirable on a web server.
What are you trying to accomplish? Is there another way you might go about it?
I found this nice article about how to use async worker, will give it a try. http://www.dotnetfunda.com/articles/article613-background-processes-in-asp-net-web-applications.aspx
And this:
http://code.msdn.microsoft.com/CSASPNETBackgroundWorker-dda8d7b6
But I think for my needs this one will be perfect:
http://forums.asp.net/t/1433665.aspx/1
for a backup program I am doing I have already finished the GUI. Now I want to do the functional requirements. Each backup can have schedules. There are predefined settings like every Sunday or Monday but the user can also specify his own schedules.
As I have never done anything like this, I was wondering what a good approach would be to running a backup every x hours or days. I was thinking about using Threads or writing a service but both fields are totally new to me. What would be the best method here?
If threaded development and service development are both totally new then I think you will struggle to implement this in a useful way. Even so...
Scheduler-type applications are best run as services, because otherwise you need the user to be logged in to be running the application. Services run independently of the user being logged in.
Because of this, however, services don't have a user interface so your GUI needs to package up the details of schedule into a configuration file somewhere, then signal the service to re-load that configuration file so that the service will then know what to do and when to do it.
The service will normally spawn a worker thread to do pretty much everything, and that worker thread needs to be able to respond to the service being shut down (read up on AutoResetEvent to see how this might be done across threads). The thread will then wait until either an event or for the appropriate time to arrive and then do whatever it has to do.
None of this is actually complicated, but I suggest you do some digging into multithreaded programming first.
I agree with ColinM, Services are best for the Scheduler Type of application.
You have to combine the Services with application to run your code at scheduled intervals.
See the article for more details - http://msdn.microsoft.com/en-us/magazine/cc163821.aspx
I am creating a web application in which I need to allow the user to schedule the excecution of a task.
I have gone through the various threads for scheduling the task but all of them are using windows service that I am not aware of. Moreover I cannot install visual studio in the server systems due to budget constraints.
Is there a way to create a method that runs a scheduler in a background thread in the asp .net application.Any code sample will be of great help.
That's not the way to go. If you need a scheduled task you should create a console application and run it using the Windows task scheduler.
You could create an application that sends an email to the user with a link to the page where the task is supposed to be done.
One thing to understand is that ASP.NET is intended to service requests from the network.
Everything in it is geared towards that. So, yes, you can run background tasks, but there are a number of caveats and gotcha's.
For instance, IIS will shut down your ASP.NET application if it does not receive any requests for some period. Also, your Application may be restarted without warning, if it detects changes to the file system. So, running code will be aborted.
That's not to say you can't work around these, but it's really not the best fit for scheduled task execution.
Your best bet would be to store the details of the task in a database, and then using either a single always-running Windows Service (really not that difficult to do, there are plenty of examples), or a console application (as suggested) scheduled manually to run regularly, to execute these tasks.
You may find that a library such as Quartz.NET may be of help scheduling/running these tasks.
My issue is pretty simple.
I have an application that should be executed automatically once a day. I have no prior experience with this kind of scenario (some time ago I worked with IBM Control-M but guess that it is way more complete, complex and expensive =))
I thought about two possible solutions:
Creating a Task inside Windows Task Scheduler, which would execute the application;
Implement the application as a Window Service which would run 24/7, but only would perform the needed actions depending on the current time.
Which are the advantages/disadvantages of each approach?
Is there another way to do this?
Thanks in advance.
If it only executes once a day (or so) then just do it as a regular command line app that is executed by the windows task scheduler. Task scheduler already has all of the UI necessary to determine when to kick off the program, pass in parameters and anything else related to the scheduling of the task.
The only real reason to do this type of function as a windows service is if it needs higher execution resolution than once a minute. However, the main downside to a windows service is that you would have to manage the logic for how often/when to kick it off. Another one is that the app is always running, which leaves open the possibility for leaked memory if your code has issues.
On Unix/Linux you would use a cron job schedule a task to be executed. MS Windows' version is called the Task Scheduler and it is already a service that run 24/7 and performs the needed actions depending on the time.
Create a repeating task with the Task Scheduler to run your application. Creating, installing and configuring a service application is not exactly trivial. It's a much more involved process than creating a standard Forms or command line app and you don't need to do it anyway.
http://msdn.microsoft.com/en-us/magazine/cc164015.aspx
http://www.dotnetmonster.com/Uwe/Forum.aspx/dotnet-csharp/70633/Waitable-Timer-in-C
Another library that might be of interest is Quartz.NET
Folks,
I want to develop a long running windows service (it should be working without problems for months), and I wonder what is the better option here:
Use a while(true) loop in the OnStop method
Use a timer to tick each n seconds and trigger my code
Any other options ?
Thanks
Essam
I wouldn't do #1.
I'd either do #2, or I'd spin off a separate thread during OnStart that does the actual work.
Anything but #1
The services manager (or the user, if he's the one activating the controls) expects OnStart() and OnStop() to return in a timely fashion.
The way it's usually done is to start your own thread that keeps things running and ofcourse, listens to an event that might tell it to stop.
Might be worth considering a scheduled task with a short interval. Saves writing a lot of plumbing code and dealing with the peculiarities of Windows Services timers.
Don't mess with the service controller code. If the service wants to stop, you will only make matters worse by using #1. And BTW the service can always crash, in which case your while(true) won't help you a thing.
If you really want to have a "running windows service (it should be working without problems for months)", you'd better make sure your own code is properly and thoroughly tested using unit and integration tests before your run it as a service.
I would NOT recommend #1.
What I’ve done in the past for the exact same scenario/situation is create a scheduled task that runs ever N seconds, kicks off a small script that simply does these 2 things: #1 checks for “IsAlreadyRunning” flag (which is read from the database) #2 If the flag is true, then the script immediately stops end exits. If the flag is false, the script kicks off a separate process (exe) in a new thread (which utilizes a service to perform a task that can be either very short or sometimes really long, depending on the amount of records to process). This process of course sets and resets the IsAlreadyRunning flag to ensure threads do not kick off actions that overlap. I have a service that's been running for years now with this approach and I never had any problems with it. My main process utilizes a web service and bunch of other things to perform some heavy backup operations.
The System.Threading.Timer class would seem appropiate for this sort of usage.
Is it doing a
1 clean up task, or
2 waking up and looking to see if needs to run a task
If it is something like #2, then using MSMQ would be more appropriate. With MSMQ task would get done almost immediately.