Okay, so let's say I have a web application that absolutely has to perform some kind of startup and has to remain running indefinitely regardless of the communication it receives from the clients (as it's a push based system)
Now for testing I have been hosting this as a windows service, which is great because it allows for me to have a hard entry point to the application where I can do my bootstrapping and get the service up and running
Next, I'm trying to move this into the IIS world instead so I can face this service to the outside world...and I've hit a snag...I don't have any hard entry point where I can bootstrap the application except for global.asax, which as I understand it is only invoked when the clients make a call to the server
Is there a better area I can put an entrance to the application and get it bootstrapped without waiting for a client to connect to it? And is this area only called once or is it going to be called periodically as the application falls out of scope (so to speak)? Like I said, the app has to remain running at all times
Is there a better area I can put an entrance to the application and get it bootstrapped without waiting for a client to connect to it?
Yes, there is. You can warm up IIS.
And is this area only called once or is it going to be called periodically as the application falls out of scope (so to speak)?
It depends which method in Global.asax you use. Application_Start runs once per app start.
Like I said, the app has to remain running at all times
Beware, dragons here. This depends how critical it is. If you need utter reliability, you must use load balancer and have at least one other duplicate service. Other things to consider, app pool needs to be recycled from time to time. IIS, OS, your application have bugs, updates needs to be installed, network device fails, power outages do happen and so on.
Related
How to host a Windows Service in IIS and keep that service runing like it is running on Windows?
Could I use some feature from WCF service?
I've not access to the Windows itself, only to IIS. Inside that service I'll create a thread which at scheduled time will process some data.
In short, you can't.
A more detailed answer is that there are 2 problems:
IIS worker processes are launched only when a HTTP request comes in. This means you can't start your service with the system.
IIS worker processes are recycled (i.e. restarted) on several conditions. For example, a worker process is restarted if no HTTP request comes in for a long time. This means you can't control when your service is shut down, unless you have access to application pool recycling configuration. Keep in mind that the recycling logic only ensures that all pending HTTP requests are complete, but does not await all background threads to complete.
You can come with a partial solution this way:
Create a WCF service method that checks if your long-running thread is alive and if not, starts it.
Create a very simple windows service that periodically (once in 5 seconds) calls that method. Deploy the service somewhere, e.g. on your own machine.
The only question that remains is: do you really need to avoid windows services? Could you find a place to host the service? There are some use cases when a windows service is the best or even the only way.
You cant, in a nut shell.
However you can make use of the health monitoring API specifically the heartbeat functionality. see:
http://msdn.microsoft.com/en-us/library/system.web.management.webheartbeatevent.aspx
for details on the class you will need to implement to be called when there is work to do
also this answer on SO might help
Understanding heartbeat in ASP.NET health monitoring
Once you have implemented a webheartbeatevent derived class you can check your db or what ever you want to check if there is work to do.
A better solution IMHO is to scrap the service entirely and redesign the system to be 100% web based, as services become a deployment and maintenance nightmare. as i assume you are now finding out...
So I created a Windows Service using C# and created an installer in Visual Studio for it. It's set up to run manually as I don't want it running all the time. I then have another application (C# WPF) that should have an option to turn the service on and off (the service itself creates a web service that in turn communicates back to my WPF application). This works fine in Windows XP, but testing it on a Windows 7 machine, it won't start. Surprisingly it does throw an exception and crash, it just does nothing. I believe this is a permissions problem. If I go to the services control panel using the same Windows 7 account, I'm not able to start or stop the service either.
So my question is, is there a way to set my service so that regular user accounts can start and stop it? And is there a way to set my installer to do this automatically.
I don't want my WPF application to have run as administrator!
Whilst I believe that it is possible to secure a service so that regular users can start and stop it, I do not recommend doing so. This will create a lot of complication and is a potential cause for confusion. I always prefer to keep things simple, especially when it comes to installation and security.
So, if we can't let the user start and stop the service we probably need to let the service run all the time. Since you don't want the service to be active all the time I suggest you give the service its own internal Running flag. When this is set true, the service is active and does busy things, otherwise the service remains idle. You can use your preferred IPC mechanism (sockets, named pipes, WCF etc.) to allow the user to toggle this switch.
Windows 8 has a feature to allow services to start on demand, basically in response to some kind of trigger. But for Windows 7, your only real option is to set it to start automatically on startup. You could set it to start delayed, so that its not adding to the time it takes windows to start.
Regular users cannot start and stop services.
EDIT: Reading the link in the comment above it sounds to me as that is a blanket ability for users to start and stop services. I think the question here is about how to do this for a particular service.
Also, while it may be possible to set the service to run as that particular user, it really means it only works for that particular user and other users on the work station would not be able to use the application as they'd not be able to start or stop the service, assuming that the service running as a user implies that the user may control it, which may not be the case.
Also in reading the comments and other answer, I'm left to wonder if the service can be used by any user which can run the application. That is, if user A logs on to the work station and starts this app (and thus the service), locks it and walks away, what happens when use B logs on and tries to run the same service? Can the service support multiple users at the same time, or will funny things begin to happen if the service is utlized by the application running multiple times.
This really sounds like what is desired is for a background to be started when the application starts. This thread (or threads) would do the work of the service, and by their nature would end when the application ends. Of course more detail in the question would help give a better answer.
Of course if it is appropriate as a service, I see no reason not to have a service with a worker thread that sleeps, and another timer thread that acts as a producer that checks if there's work to do.
I have seen examples, sample codes etc for self hosting WCF services within a console app, windows service etc.
My question is, how will this work in production? Will it be efficient? Will it scale?
I m not sure, how it will work, so other question is, will that be single threaded? multi threaded? do i need to manage the multi threading? appdomains?
I prefer hosting with command line, windows service for application related reasons.
My question is,
Will it be efficient? Will it scale?
Yes and yes. But for really large scale apps you should still consider IIS (+WAS).
so other question is, will that be single threaded? multi threaded?
That is determined by the configuration.
Will it be efficient?
It depends on the service implementation, on the maximum number of requests it is able to manage within a specific time-frame. Efficiency is a relative measure: let's assume your service is able to process 20 messages/sec, if your requirement is to be able to process 10 messages/sec, then your service is efficient. But if the requirement is 30, then it is not.
Will it scale?
Once again, it is not related to hosting. Are your services stateless? if not then, they probably won't scale much since load balancing is not possible.
Will it be manageable ?
Probably not:
- you need to have a user logged on the server to run the app
- it does not auto-start with the server
- it cannot auto-restart on failure
- it does not create instances of the service pro-actively
- it does not provide (without custom code) a way to check the service health
Single instance ? Multiple threads ?
If your service does not maintain state between calls per client, then configure it as "one instance per call and no multithreading" -> No concurrency, high throughput
If your service does maintain state, then configure it as "one instance per session and multithreading" to allow a client to perform concurrent calls. Be careful about concurrency issues and protect your resources.
If your service does not maintain state per client but keeps some global data stored for all calls, consider the "single instance per service and multithreading". Keep in mind the possible concurrency issues. In that you might as well use "one instance per call" and keep the global storage out the service.
A Windows service hosting a WCF endpoint is fine for small services that aren't going to be hit often; you don't have to mess with IIS (which can be a REAL pain IMO). However, there will only be one listener listening, so it's not recommended for a service that is likely to be hit from several places at once (use IIS for that; it sets up an app pool that can handle many simultaneous requests). This model is good for one-on-one interop between two machines; you might set up the service host on a "set and forget" box living out in a warehouse somewhere, and call it to perform simple but custom tasks like rebooting, log dumps, etc.
Avoid having any user app (console or otherwise) host a service endpoint, except for initial proof-of-concept testing. In addition to the single-listener drawback, a user app MUST be run in the context of a logged-in user (not the service users, which are "logged in" as part of Windows startup), and must have custom "keepalive" monitoring; with a service, Windows can be told to simply restart it if it crashes, while it doesn't give a toss about a user app crashing other than to prevent that program taking down the whole OS (and to ask the user if they want to report the crash).
Question: When a webapplication gets started, it executes Application_Start in global.asax.
Now, a web application gets started as soon as the first request for a page in that application reaches the server.
But my question is: how long will the application run until the application is stopped.
I mean when after the first page request, there's no traffic on the server.
I need to know because I intend to start a server that listens on a tcp port in global.asax.
And when the application stops, the server ceases to listen to its port.
It depends on your IIS settings. Your application will run in an application pool, which takes a bunch of settings defining the behaviour of this pool.
The thing you're looking for are recycling settings. In IIS 7, you can access these easily from the management console. Go to Application Pools, right click on the application pool your app runs in (if you don't know which one that is, then it's probably the DefaultAppPool) and select recycling.
Here you'll find the options you have to control the recycling behaviour of your app pool, which in turn controls when your app 'resets'.
in a word (well 2) - shared hosting.
on shared hosting beware, (godaddy/webhost4life etc) this timeout could well be less, plus you don't have option to configure that on these hosting environments. i've had cases where the app pool is recycled after 5 mins at certain peek times, so you might have to investigate 'wakeup' routines to poke your app to keep in in the memory. i do this for a few shared hosting apps to great effect using pingalive.com.
hope this helps, even if in an abstract way.
jim
I need to implement a background process that runs on a remote windows server 24/7. My development environment is C#/ASP.NET 3.5. The purpose of the process is to:
Send reminder e-mails to employees and customers at appropriate times (say 5:00PM on the day before a job is scheduled)
Query and save GPS coordinates of employees when they are supposed to be out on jobs so that I can later verify that their positions were where they were supposed to be.
If the process fails (which it probably will, especially when updates are added), I need for it to be restarted immediately (or within just a few minutes) as I would have very serious problems if this process failed to send a notification, log a GPS coordinate, or any of the other tasks its meant to perform.
Implement your process as a Windows service.
For a straightforward example of how
to code a Windows service this in
.Net see http://www.developer.com/net/csharp/article.php/2173801 .
To control what happens should the
service fail configure this through
the "Recovery" tab on your service
in services.msc. (see image below)
For higly critical operation you
might look into setting up a server cluster for mitigating single
server failure (see http://msdn.microsoft.com/en-us/library/ms952401.aspx ).
(source: microsoft.com)
You need a Windows Service. You can do non-visual iterative operations in windows services.
Another alternative is to create a normal application and run it on a schedule. Your application is run at certain times a day to perform its actions, depending on how often you need to log GPS coordinates and send reports. If your service doesn't need to run constantly this is usually the recommended approach, as services are supposed to be limited to always-on applications.
As well as being a service, you might want to run on a cluster, and make your service known to the cluster management software.
You can create Windows Service (server programming on Windows) or use scheduler to periodically execute a task.
Depending on the requirements for the high availability, program can be installed on a fail-over cluster where there will be other server (passive node) started and quietly waiting as a hot-backup if the first (active node) dies. This is wide topic. Start with High availablity on Wikipedia.
In my experience if you need to run something 24x7 you need to have (one or more) watchdog process to verify that your service(s) are running correctly. Just relying on the normal service framework cannot guarantee that the program is working correctly - even if it looks like it is running. The watchdog program (which also is a service) can query the service automatically e.g. posting messages checking response times, querying for statistics and so on - when it detects problems it can restart the service (or do some other fail-recovery)
The reason for having a watchdog program as opposed to just rely on user queries to detect errors is that it can be done automatically. This is the preferred method because it allows for a proactive detection.