I'm planning to host the service in windows service, but I'm thinking about the problem described in the title. Anyone had similar issue?
Thanks
Update
The problem is that when you throw an exception in WinForms/WPF/Win Service app, the program crashes and you'll have to restart it.
An exception does not always crash your server. Even an unexpected server-side exception will be transferred to the client. It is considered more severe than an expected one though, faulting the channel.
The basic idea is to include the expected exceptions (faults) in you interface contracts . There are many ways to do that, here is an introduction article.
And of course you need decent exception handling at the server.
A thing you can try is to intercept any exceptions by hooking to the ThreadException event in the Main method entry point of your Host application to check whether it is a FaultException.
static class Program
{
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
// Hook to this event below
Application.ThreadException += new System.Threading.ThreadExceptionEventHandler(Application_ThreadException);
}
static void Application_ThreadException(object sender, System.Threading.ThreadExceptionEventArgs e)
{
if (e.Exception is FaultException)
return; // Bypass FaultExceptions;
else
throw e.Exception; // Throw otherwise
}
}
Related
I am trying to keep the (beta version of my) application running as much as possible,So I placed another try-catch inside Program.cs as well in cases where some critical errors occur and shut the application down unexpectedly.And in the catch i rewrote the Application.Run() method so that the application can resume itself after being terminated for what ever reason.
Is it right to have such a plan for this specific scenario?
If it is not right,Then what else is recommended in order to keep the program running?
This is the sample code demonstrating what i mean:
using System;
using System.Collections.Generic;
using System.Windows.Forms;
using Hossein;
using Pishro.Classes;
namespace Pishro
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
try
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new frmMain());
}
catch(Exception exc)
{
API.SaveAndShowLog(exc);
Application.Run(new frmMain());
}
}
}
}
Globally handling exceptions is a good idea for logging and alerting.
An automatic restart policy like yours can be useful, yes. There is a risk however: If the crash has corrupted global data-structures restarting the app can have unpredictable results like silent data corruption. For example, files might still be open and locked. Locks might not have been released. Static variables might be in an undefined state. Rogue threads might still be running, unaware that the application UI was destroyed.
I recommend that you restart the app by starting a new process of your application. Let the old process die.
I think your question involves a deeper question.. Should I catch all the exceptions?
To keep going you could catch them all.. but all those possible exceptions that you don't expect or not know are probably bugs.
Maybe you should try to implement better error handling approach within your app. So all the exceptions are known or expected.
Instead of wrapping a try catch around your application run method, consider handling the exceptions with events.
static void Main()
{
AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
Application.ThreadException += new System.Threading.ThreadExceptionEventHandler(Application_ThreadException);
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
static void Application_ThreadException(object sender, System.Threading.ThreadExceptionEventArgs e)
{
MessageBox.Show("Exception handled");
}
static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
}
Mainly the thread exception is the one you want but ideally - you would want to set up some form of logging/flagging the error to the user and still dispose of the program because it may cause the program to continue in an unfit state. Please put a button on your form and in the click event throw new Exception(""); and then the message box should display.
I cant seem to make heads or tails of how I am supposed to properly handle unexpected exceptions.
Consider the following application:
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new SomeForm());
}
class SomeForm : Form
{
public SomeForm()
{
Button btn = new Button();
btn.Text = "Click ME";
btn.Location = new System.Drawing.Point(20, 20);
btn.Click += new EventHandler(btn_Click);
Controls.Add(btn);
}
void btn_Click(object sender, EventArgs e)
{
throw new Exception("This is an Exception");
}
}
If I run this application and click the button I get an unhandled exception as expected. At first I tried surrounding the Application.Run with a try catch block like so:
try { Application.Run(new SomeForm()); }
catch { MessageBox.Show("Exception caught in try catch"); }
At first this seems to work, until I ran the application outside of the Debugger. When you run the application outside of the Debugger, the exception is reported as an unhandled error. After doing some reading I discovered I should be looking at the Application.ThreadException event. So I do the following:
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.ThreadException += new System.Threading.ThreadExceptionEventHandler(Application_ThreadException);
try { Application.Run(new SomeForm()); }
catch { MessageBox.Show("Exception caught in try catch"); }
}
static void Application_ThreadException(object sender, System.Threading.ThreadExceptionEventArgs e)
{
MessageBox.Show("Exception caught in event");
}
Now when I run my application outside of the debugger the exception is handled and the MessageBox indicates it was caught in the event handler. Then I go back into the debugger and run it. Now the Debugger kicks it up as an unhandled exception even though I have surrounded it in a try catch AND I am tied onto the Application.ThreadException event. If I do not tie up the to Application.ThreadException event the exception is caught correctly by the try catch block.
Now to the questions:
What the heck is going on here?
Is there a way that I can catch/handle all exceptions in my application that works both in the debugger and outside of the debugger?
Am I just doing the completely wrong thing here?
You can handle them using AppDomain.CurrentDomain.UnhandledException and Application.ThreadException, look for more.
What's the difference between Application.ThreadException and AppDomain.CurrentDomain.UnhandledException?
The debugger considers exceptions that propagate to Application_ThreadException to be unhandled exceptions, since that event handler is used as a final location to log and terminate gracefully. This allows you to stop at the point of the exception when running the debugger, which is often very helpful.
It's not possible to handle all exceptions in one global place because there is not enough context to know how to actually handle them. You can catch all exceptions (even the unhandled ones) using Application_ThreadException (and AppDomain.UnhandledException for exceptions on other threads), but the next thing you should do in that case is shut down your application.
You should handle exceptions in each method separately, based on the information you have and the knowledge of the types of exceptions that can occur. Exceptions you don't know how to handle should not be caught and will percolate to the 'global' event handlers, which should log the details and politely shut down the application.
I tried to write a little crash reporter for uncatched expetions. This works perfectly when starting my App in VS.
But as soon as I try to start the .exe it only shows me the standard "There is an uncaught expetion"-thingy from windows.
And no it's not the crashreporter which crashes.
This is my code in the Program.cs
try
{
Application.Run(new TestServer());
}
catch (Exception e)
{
Application.Run(new CrashReporter(e.StackTrace.ToString()));
}
}
This is because you use a debugger. Winforms detects this and disables the event handler for Application.ThreadException. That's important, it lets you debug exceptions. To get your catch clause to work without a debugger, you'll have to add this statement to your Main() method, before the Run() call:
Application.SetUnhandledExceptionMode(UnhandledExceptionMode.ThrowException);
It now does make more sense to write an event handler for AppDomain.Current.UnhandledException instead, you'll also get notified about unhandled exceptions in worker threads.
Instead of this you can handle following event (which is the preferred way of handling unhandled application exceptions):
AppDomain.CurrentDomain.UnhandledException += (sender, e) =>
{
Application.Run(new CrashReporter(e.StackTrace.ToString()));
}
Application.Run(new TestServer());
Are you running on a 64 bit OS? This sounds like the problem Hans Passant answered here.
Debugging can swallow errors on Form construction and Forms_Load in 64 bit CLR...
Are you sure this thing works? I mean, did this strategy work for you previously?
I use (and suggested way) this way to catch the unhandled exceptions globally:
AppDomain.CurrentDomain.UnhandledException +=
new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
//then start the main form...
Application.Run(new TestServer());
Here is the documentation
http://msdn.microsoft.com/en-us/library/system.appdomain.unhandledexception.aspx
CrashReporter is causing it. An uncaught exception in a catch statement will cause an uncaught exception. You need another try/catch in your catch and another fall back.
I have an app, and after about 20 minutes of idle time the program just crashes. ("Windows has encountered an error and needs to close...")
I have no idea why this is happening. What is the best way to go about debugging something like this?
Generally crashes in .Net applications are caused by an unhandled exception - i.e. an exception in a thread in that application that was not caught in a try-catch block of some sort:
try
{
// Some code that may throw an exception
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
A good first place to check for information about this exception is the application event log, often however you will find that the .Net framework posts only minimal information about the crash - if this is the case then you need to catch and handle the exception yourself, recording enough information to allow you to diagnose the error.
Typically there are two way that you might do this:
1. Ensure that the code for each thread of your application is contained in a try-catch block.
This is the easiest method - unless your application has multiple user threads (you will know if it has), this simply requires that you place a try-catch block around the entry point of your application, for example in a Windows Forms application:
// Probably found somewhere in Program.cs
[STAThread]
static void Main()
{
try
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
If you are working on a console application then you will need to use something other than MessageBox (see the first example).
If you spawn multiple threads then the entry point method for each thread should also catch all exceptions in a similar way.
2. Handle the UnhandledException event of the current App Domain
This event will be fired whenever any thread throws an unhandled exception in the current App Domain. Generally speaking it is best to use the first method instead, however this event is still useful in some situations.
Example:
static void Main()
{
AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
// The rest of your application
}
static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
Console.WriteLine(e.ExceptionObject.ToString());
}
Of course it is worth pointing out that the error still might not be caught by either of the above two methods (which is possible if the error is caused by a native module loaded in the same process), however this should probably do the trick.
Finally - Good luck!
protected override void OnStart(string[] args)
{
AppDomain.CurrentDomain.UnhandledException +=
new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
Thread.Sleep(10000);
throw new Exception();
}
void CurrentDomain_UnhandledException(object sender,
UnhandledExceptionEventArgs e)
{
}
I attached a debugger to the above code in my windows service, setting a breakpoint in CurrentDomain_UnhandledException, but it was never hit. The exception pops up saying that it is unhandled, and then the service stops. I even tried putting some code in the event handler, in case it was getting optimized away.
Is this not the proper way to set up unhandled exception handling in a windows service?
The reason that the UnhandledException event on the current AppDomain does not fire is how services are executed.
User sends a Start command from the Windows Service Control Manager (SCM).
The command is received by the framework's ServiceBase implementation and dispatched to the OnStart method.
The OnStart method is called.
Any exception which is thrown by OnStart is handled in the base class, logged to the Event Log, and translated into an error status code returned to the SCM. So the exception never propagates to the AppDomain's unhandled exception handler.
I think you would find that an unhandled exception thrown from a worker thread in your service would be caught by the AppDomain's unhandled exception handler.
In a Windows Service you do NOT want to be running much code in the OnStart method. All you want there is the code to launch your service thread and then return.
If you do that you can handle exceptions that happen in your service thread just fine.
e.g.
public static void Start()
{
AppDomain currentDomain = AppDomain.CurrentDomain;
currentDomain.UnhandledException += new UnhandledExceptionEventHandler(currentDomain_UnhandledException);
running = true;
ThreadStart ts = new ThreadStart(ServiceThreadBody);
thread = new Thread(ts);
thread.Name = "ServiceThread";
thread.Priority = ThreadPriority.BelowNormal;
thread.Start();
}
When I was working on my own Windows Service, it was stoping itself oddly enough. I thought it was because of unhanded exception. At the moment I am catching unhanded exceptions on text file. First of all you have to create new file ServiceLog.txt on C locations due to logging excaptions on text file. With below coding I got all unhanded exceptions with them line numbers.
using System.Security.Permissions;
using System.IO;
[SecurityPermission(SecurityAction.Demand, Flags = SecurityPermissionFlag.ControlAppDomain)]
protected override void OnStart(string[] args)
{ AppDomain currentDomain = AppDomain.CurrentDomain;
currentDomain.UnhandledException += new UnhandledExceptionEventHandler(MyHandler);
...
Your codes...
....
}
void MyHandler(object sender, UnhandledExceptionEventArgs args)
{
Exception e = (Exception)args.ExceptionObject;
WriteToFile("Simple Service Error on: {0} " + e.Message + e.StackTrace);
}
private void WriteToFile(string text)
{
string path = "C:\\ServiceLog.txt";
using (StreamWriter writer = new StreamWriter(path, true))
{
writer.WriteLine(string.Format(text, DateTime.Now.ToString("dd/MM/yyyy hh:mm:ss tt")));
writer.Close();
}
}
Know this thread is a bit old, but thought it would be useful to add some comments based on personal experience developing Windows services in .NET. The best approach is to avoid developing under the Service Control Manager as much as you can - for this you need a simple harness that mimics the way services get started - something that can create an instance of your service class (that you already derived from ServiceBase) and call your OnStart, OnStop etc methods. This harness can be a console app or a Windows app as you desire.
This is pretty much the only way I have found of debugging service start-up issues in .NET - the interaction between your code, Visual Studio and the real Service Control Manager just makes the process impossible otherwise.
HTH.
Just curious, what are you trying to accomplish: avoiding service crashing, or reporting errors?
For reporting, I think your best bet is to add top-level try/catch statements. You can try to log them to the Windows event log and/or a log file.
You can also set the ExitCode property to a non-zero value until you successfully stop the service. If the system administrator starts your service from the Services control panel, and your service stops suddenly with a non-zero exit code, Windows can show an error message with the description of the error.