I am using C# to write a program that uses a web service from http://msrmaps.com, the problem is sometimes (seemingly at random) the site won't work properly and will return a few different exceptions. Then on subsequent attempts to use the service I get the error over and over, then after a while (sometimes 30 minutes) the service starts working properly again. In order to avoid waiting for the service to work properly again, I usually just close my program and start it back up again. Usually that fixes the problem and I can continue to use the web service.
My question: Is it possible to restart my program within the program or better yet is there a way to somehow re-connect to the web service like the program does when I first run it?
What is the program actually doing that depends on the web service? Does it really need to be re-started? It sounds like you should be able to just have some UI element in the application that attempts to connect to the service. Wrap that connection in some exception handling and somewhere in the application's UI display that the service connection is currently unavailable.
Or am I way off here?
Warning: This is a bit of a hack, but it works.
I'm assuming your application is unattended, so a UI change alerting the user to the need to shut down and restart is not an option.
We had a similar situation where the simplest resolution to a problem was to shut down and restart my app. (We'll call this "App A").
What I wound up doing was writing a second executable (We'll call it "App B") as a console app that did two things.
It used the System.Diagnostics.Process to kill any instance App A.
Use System.Diagnostics.Process to re-launch App A after all instances were killed.
Then in App A, I had a try/catch around the offending code, and when the error I was looking for came up, it would call App B.
This was the only way I could find of killing a program and relaunching it. If anyone has a better solution, PLEASE post it and I'll change my hack to use a better solution.
I would check that you don't have too many simultaneous requests happening at the same time due to each waiting for a long time before returning (and relatedly, that the total allowed connections as per machine.config is high enough). Throttling code can be very useful with unattended use of web-services (or any other remote service), if you've had a few failures in a row then wait a while before allowing another request to be made (I like to roll forward the wait period each time, starting a around a minute, maxing the wait at around 10minutes).
Then while you can't guarantee the other service won't go down, you can help prevent it causing a permanent problem, or reducing the performance of other processes.
Related
I have a service application written in C# and under certain circumstances, I would like it to terminate itself. This would happen after the service has been running for a while, so this would not be happening in the OnStart() event.
Everything that I have read so far suggests that the only safe way to terminate a service is through the Service Control Manager. My service runs as Local Service and does not have the rights to start or stop services, so I can't access the SCM from the service itself. Is there another way to self-terminate while still playing by the rules of the SCM?
Try ServiceBase.Stop().
If you want to terminate the service instead of stopping it (perhaps because the service has caught an otherwise unhandled exception) you can use Environment.Exit(1) (use another exit code if you want).
Windows will discover that the service has terminated unexpectedly. If the service has been configured to recover the recovery procedure will be used which includes options for restarting the service, running a program or restarting the computer.
What happens if you just let all the executing threads finish? I can imagine three possible outcomes:
The SCM notices, and decides you finished appropriately
The SCM notices, thinks you died, and restarts you
The SCM doesn't notice, and shows you as still running
EDIT: I suspect this answer is the best one really, but I'll leave this up (for the moment) just for the sake of interest.
Don't have the service run under Local Service. Have it run under a user that has the rights to stop a service.
Although the idea of self-terminating services is not the best of ideas. That very fact alone means that it should be an application, and not a service.
I have a service application written in C# and under certain circumstances, I would like it to terminate itself. This would happen after the service has been running for a while, so this would not be happening in the OnStart() event.
Everything that I have read so far suggests that the only safe way to terminate a service is through the Service Control Manager. My service runs as Local Service and does not have the rights to start or stop services, so I can't access the SCM from the service itself. Is there another way to self-terminate while still playing by the rules of the SCM?
Try ServiceBase.Stop().
If you want to terminate the service instead of stopping it (perhaps because the service has caught an otherwise unhandled exception) you can use Environment.Exit(1) (use another exit code if you want).
Windows will discover that the service has terminated unexpectedly. If the service has been configured to recover the recovery procedure will be used which includes options for restarting the service, running a program or restarting the computer.
What happens if you just let all the executing threads finish? I can imagine three possible outcomes:
The SCM notices, and decides you finished appropriately
The SCM notices, thinks you died, and restarts you
The SCM doesn't notice, and shows you as still running
EDIT: I suspect this answer is the best one really, but I'll leave this up (for the moment) just for the sake of interest.
Don't have the service run under Local Service. Have it run under a user that has the rights to stop a service.
Although the idea of self-terminating services is not the best of ideas. That very fact alone means that it should be an application, and not a service.
A test WCF webservice that I have hosted using IIS 7.5 is consistently slow to respond to calls made after a period of inactivity (i.e. the first call of each day).
From researching this topic I gather that the problem of "application warmup" is commonly encountered when using IIS (e.g. see here).
I have taken the usual steps that are recommended to try and mitigate this problem:
Installed the Application Initialization Module.
Disabled the application pool Idle Time-out, and the Regular Recycling Time Interval (i.e. set them to '0').
Edited the applicationhost.config file so that autoStart=True and startMode="alwaysRunning" for the necessary app pool, and preloadEnabled="true" for my application.
With these settings, I expect the application pool to immediately spin up a worker process when IIS is started, and spin up a new worker process when the existing one exits. Also, I expect the application to be loaded within the worker process.
However, for the first call of each day, the logs show the difference in time between the client making a call, and the webservice receiving the call, can be as much as 10 seconds. Subsequent calls are typically handled in well under 2 seconds.
Curiously, the long response time is not reproduced by making a call following an iisreset command. I would expect that such a heavy-handed operation would put the webservice in a similarly "cold" situation, however this does not seem to be the case.
I would like to know:
What could still be causing the delay in the application "warming up"?
What is the difference in the state of the webservice following iisreset and a long period of inactivity?
Should I resort to a "heart beat" solution to regularly ping the service to keep it alive?
Thanks in advance for any tips or insight.
I'll try to help with you questions:
What could still be causing the delay in the application "warming up"?
Warm up an application does not mean warm up its resources. For instance, if you configure Auto-start with Application Fabric in your WCF application (https://msdn.microsoft.com/en-us/library/ee677260(v=azure.10).aspx), and this application access database using EF, it will not initiate your DBContext.
If you want these resources initialized after your application warmed up, you need to implement a method to initialize your resources, like cache, DBContext, etc.
What is the difference in the state of the webservice following iisreset and a long period of inactivity?
When the application spend long time of inactivity, probably the application pool goes down and it is restarted when it receives any request, like a recycle does.
This link has interest information about the difference between iisreset and application pool recycle, and it can help to answer your question: https://fullsocrates.wordpress.com/2012/07/25/iisreset-vs-recycling-application-pools/
Should I resort to a "heart beat" solution to regularly ping the service to keep it alive?
If you keep on accessing your service, it will probably keep its resources initialized in memory, so can be a good approach.
Anyway, if your Application Pool is configured to recycle in some interval time, it will be recycled and your resources in memory lost.
If it looks problem to you, just turn off this feature going to IIS -> Application Pool -> Advanced settings and set Regular Time Interval=0
For this issue, it's just some suggestions, you need to make some tests and find out the better solution.
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 a requirement that a Windows Forms C# .NET 2.0 program running in user-space (not a service) must always be running. As I'm not infallible and make coding mistakes, I wanted to know of any extra safeguards I could use to ensure this requirement is met. The things I've been thinking of are TaskScheduler to check it every 5 minutes, A stub watcher or a secondary process. Are these good / bad ideas?
Thanks,
Richard
EDIT: The reason I didn't use a service (the obvious and sensible answer!) was the program runs in a kiosk type environment and has has a heavy GUI component. The service option didn't work well across Windows 2000 - W7.
EDIT: The second reason not to use a service was the app needs internet access and on some of our customer sites, proxies are set up to only allow specific users (not the local system account) so it would be tricky to ensure access if multiple users log onto the machine.
Task scheduler is a cheap solution for this which does work. I use this to keep our Perforce Proxy server running (had some issues with the service), and so far there's been no problems - though now I've said that the server's probably exploded!
However, the most complete solution is a Windows service which invokes your app. You can make that service catch error return codes from the app, restart it on failure and notify you by email, which may help you diagnose and fix those issues. I think the Task Scheduler does something similar but it won't be able to provide as much insight into your application as a custom service.
If you're unsure of how to do that, then something like this should work:
http://www.codeproject.com/KB/install/csharpsvclesson1.aspx
There are three approaches that you can take:
Heartbeat Message.
A heartbeat is useful in a distributed application and is simply message that is sent (from let say a client to server) to confirm that it is still healthy/running.
Manager Process
A stub program, implemented as either a user process or a service. It launches the main application, monitors any unhandled exceptions, reports errors, and restarts on failure.
An exception guard on the entry point.
A try-catch-all in the application entry point.
I would recommend either of the first two options; the third option, the try-catch-all, is a particular nasty hack for the lazy and inexperienced programmer (IMHO).
I have successfully used both heartbeat and manager process in a large distributed application.
UPDATE
As for ready-to-go™ restart managers, take a look at the Windows API Codepack as discussed in Emmanuel Istace blog post (http://istacee.wordpress.com/2013/09/21/automatic-recovery-restart-in-net-application/).
You can install the package from https://www.nuget.org/packages/WindowsAPICodePack-Core/