I have a service manager that checks and controls services that are connected to it. But sometimes one of my service is getting crushed and service manager can't know whether it is still working or not. (Because of the dialog box which shows debug and close options). So i found an accepted solution that catches unhandled exceptions, but doesn't work in my code.
Here is my code that doesn't catch unhandled exceptions.
static void Main(string[] args)
{
AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(unhandled_exceptions);
new Thread(() =>
{
start()
}).Start();
}
public void unhandled_exceptions(object sender, UnhandledExceptionEventArgs e)
{
this.disconnect();
logger.Error(e);
logger.Info("Catched unhandled exception, that causes to crash application. Disconecting from service manager..");
Environment.Exit(1);
}
public override void start()
{
try
{
throw new ArgumentException("erer");
}
catch (Exception ex)
{
logger.Error(ex);
}
Thread.Sleep(5000);
PerformOverflow();
}
void PerformOverflow()
{
PerformOverflow();
}
.Net 4.6, Console applicaiton
I don't know what causes to crash my application, in actual fact the start method is in a try catch blog. I am using StackOverflowException because it is not unhandled too. I think If i catch it i could catch the real one that crashes my app.
Related
I have a C# program which runs a system tray application - transferring / moving / creating / editing files in the background.
There is alot of exception handling and loop handling to prevent the program from crashing / getting stuck if the user manual deletes a file the program is working with.
Unfortunately one of the computer the program is running on is having the program crash. The computer is very hard to get, and cannot have debugging software loaded on (it is an embedded PC outside with no network access).
I have tried finding the cause of the crash (such as an unhandled exeption) however have not found anything and do not have access to the PC as it is in a remote location.
I was hoping to find a way to use AppDomain / an UnhandledExceptionEventHandler to catch all unhandled exceptions and log them for diagnosis.
However the exception I have (deliberately) created in the office inside the class "DoSomething.class", are crashing the WinForm application rather than logging the exception error.
My code is:
//Current domain for the unhandled exception handling
AppDomain currentDomain;
[SecurityPermission(SecurityAction.Demand, Flags=SecurityPermissionFlag.ControlAppDomain)]
public MainForm()
{
InitializeComponent();
currentDomain = AppDomain.CurrentDomain;
currentDomain.UnhandledException += new UnhandledExceptionEventHandler(UnhandledExceptionHandler);
CreateTimer.Interval = Settings.Default.CreateTimer;
CreateTimer.Start();
RunCopyProtocol();
ChangeFilesTimer.Interval = 10000;
ChangeFilesTimer.Start();
RunChangeFiles();
throw new Exception("ABC");
}
public void UnhandledExceptionHandler(object sender, UnhandledExceptionEventArgs args)
{
try
{
Exception ex = (Exception)args.ExceptionObject;
SetLabel(ex);
}
finally { }
}
private string SetLabel(Exception ex)
{
String str;
str = ex.Message;
Label1.Text = str;
return str;
}
private void ChangeFilesTimer_Tick(object sender, EventArgs e)
{
RunChangeFiles();
throw new Exception("2");
}
Why doesn't the throw new exception call the unhandled exception error?
How would I use AppDomain to get the unhandled exception handler to handle this exception / exceptions in the RunChangeFiles?
Code on AppDomain is based of MSDN examples
If your timer is a System.Timers.Timer the reason is documented by MSDN here:
The Timer component catches and suppresses all exceptions thrown by event handlers for the Elapsed event.
Take a look at this similar question:
How do I get the Exception that happens in Timer Elapsed event?
You'll have to catch the exceptions that are thrown in the elapsed handler, and rethrow them on a ThreadPool thread.
Using your code above and extending the answer from the referenced question:
private void ChangeFilesTimer_Tick(object sender, EventArgs e)
{
try
{
RunChangeFiles();
}
catch (Exception ex)
{
ThreadPool.QueueUserWorkItem(
_ => { throw new Exception("Exception on timer thread.", ex); });
}
}
If your timer is a System.Windows.Forms.Timer then you will need to hook into the Application.ThreadException event to handle unhandled exceptions.
Subscribe to this event prior to calling Application.Run().
You can also handle logging of the Exception in a local exception handling block before rethrowing the exception.
try
{
/// ...
}
catch (Exception ex)
{
if (ex is ArgumentException)
{
/// handle known or specific exceptions here
}
else
{
/// log then rethrow unhandled exceptions here
logExceptions(ex);
throw;
}
}
I have following error handler in my console application
Main Procedure:
AppDomain.CurrentDomain.UnhandledException +=
new UnhandledExceptionEventHandler(ErrorHandler);
Handler Procedure:
static void ErrorHandler(object sender, UnhandledExceptionEventArgs args)
{
Exception e = (Exception)args.ExceptionObject;
... Loging Error ...
//Environment.Exit(?);
}
And the problem is that error is logged but after that application failed and windows popup (application is not responding) is showed.
So i want to add Environment.Exit() to prevent that behavior, but how to specify the exitCode from the exception ? I dont want to set Exit(0) (which means everything is okay) because i also want see the error (only information that some error happened, exception is already logged) in the scheduler application which trigger this script.
Thank you
Most programmers simply use Environment.Exit(1). Almost always works just fine. But that is not technically correct, if a program dies on an exception then its exit code is normally the same as the underlying exception error code. The event handler ought not change that behavior.
Doing it right is a mouthful:
Environment.Exit(System.Runtime.InteropServices.Marshal.GetHRForException(e));
There's a FUD factor here, you can't completely trust a library with custom exception objects that don't set an error code. Still okay, the fallback is E_FAIL.
Can you use the Exception.HResult?
Consider the following code:
class Program
{
static int Main(string[] args)
{
AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException; ;
if (args.Any() && args[0] == "/t")
{
Console.WriteLine("I am going to throw an exception");
throw new ApplicationException("This is an exception");
}
else
{
Console.WriteLine("I am going to exit");
//Environment.Exit(0);
return 0;
}
}
private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
Console.WriteLine("An unexpected error has occurred");
Exception ex = (Exception)e.ExceptionObject;
Environment.Exit(ex.HResult);
}
}
Then execute this from a batch file twice - once with the /t parameter and the other without:
#echo off
cls
echo Running Console Application with no error
ConsoleApplication2.exe
echo %errorlevel%
echo Running Console Application with error
ConsoleApplication2.exe /t
echo %errorlevel%
pause
In the first run you exit with 0. I've made Main return an int and just return 0 for successful execution - you can do Environment.Exit(0) here.
With the second run that throws an ApplicationException, the UnhandledException is handled, then Environment.Exit(ex.HResult) is called.
I think the HResult is tied in to specific exceptions as per MSDN. However, you may want different exit codes depending on what caused the exception. In this case you can throw custom exceptions then have some cafuffled logic in the UnhandledException handler:
private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
Console.WriteLine("An unexpected error has occurred");
Exception ex = (Exception)e.ExceptionObject;
if (ex is MyException)
{
Environment.Exit(10009); // my own exit codes
}
Environment.Exit(ex.HResult);
}
}
class MyException : Exception
{
}
But would you really care why it failed in the console? If you get an unhandled exception then it failed. You can have lots of possible failure points. What are you really going to do with the error code? You have logged the exception out. That provides the vital information.
I have a multithreaded c# project. I have removed a lock, that locked unnecessarily shared objects, and tried to make those shared objects to be for single thread.
The thing is now the process is crashing, with no error whats so ever - not in the event viewer or when I run in debug.
Can anyone suggest a way for me to diagnose the error? Because the fact that visual studio just lets the process stop with nothing for me to work with makes me stuck. My last resort is WinDbg, and I would like to avoid that.
you could try to hook into unhandled app domain exceptions -
http://msdn.microsoft.com/en-GB/library/system.appdomain.unhandledexception.aspx
and also check out unhandled thread exceptions:
https://msdn.microsoft.com/en-GB/library/system.windows.forms.application.threadexception.aspx
(code from example in appdomain link)
using System;
using System.Security.Permissions;
public class Example
{
[SecurityPermission(SecurityAction.Demand, Flags=SecurityPermissionFlag.ControlAppDomain)]
public static void Main()
{
AppDomain currentDomain = AppDomain.CurrentDomain;
currentDomain.UnhandledException += new UnhandledExceptionEventHandler(MyHandler);
try {
throw new Exception("1");
} catch (Exception e) {
Console.WriteLine("Catch clause caught : {0} \n", e.Message);
}
throw new Exception("2");
}
static void MyHandler(object sender, UnhandledExceptionEventArgs args)
{
Exception e = (Exception) args.ExceptionObject;
Console.WriteLine("MyHandler caught : " + e.Message);
Console.WriteLine("Runtime terminating: {0}", args.IsTerminating);
}
}
// The example displays the following output:
// Catch clause caught : 1
//
// MyHandler caught : 2
// Runtime terminating: True
//
// Unhandled Exception: System.Exception: 2
// at Example.Main()
It's also a good idea to check the Exceptions that cause a Debugger-break in Visual studio.
You can find this unter Debug->Exceptions... or with Crtl+D, E
Maybe visual studio just skips the exception that is causing your crash
I have an instance of the following code that executes correctly in Debug or as a standalone Windows application:
TcpListener tcpListener = new TcpListener(IPAddress.Any, 4554);
tcpListener.Start();
while (true)
{
try
{
using (Socket socket = tcpListener.AcceptSocket())
{
// Code here is reached in Debug or as a Console Application
// but not as a Windows Service
}
}
catch (SocketException se)
{
// This is never reached
}
catch (Exception ex)
{
// This is never reached
}
finally
{
// This is never reached in the Windows Service
}
}
However, when I install it as a Windows Service, it crashes on tcpListener.AcceptSocket(), and logs the following to the Event Viewer:
An unhandled exception ('System.Net.Sockets.SocketException') occurred in MyService.exe [768]. Just-In-Time debugging this exception failed with the following error: The operation attempted is not supported.
Even trying to catch the exception I am unable to log anything more. Stepping through code in Debug accomplishes nothing because the code successfully blocks the application and waits for a client connection.
Is there a way to implement this for a Windows Service?
usr's advice (and this answer) led me to a bug in the code. The ServiceBase class contained the following:
protected override void OnStart(string[] args)
{
_worker = new Thread(ExecuteService);
_worker.Start();
}
private void ExecuteService()
{
for (;;)
{
if (_stop.WaitOne(1000))
{
new TcpServer().StartTcpServer();
return;
}
}
}
The correct implementation was to remove the for loop, which was re-instantiating the listener. Here is the final code:
protected override void OnStart(string[] args)
{
_worker = new Thread(ExecuteService);
_worker.Start();
}
private static void ExecuteService()
{
new TcpServer().StartTcpServer();
}
I thought that if I wrap the EndInvoke call with a try catch if an error is thrown then my catch block would handle it? I must being doing something wrong??? Has to be user error, just not sure what?
EDIT:
I get the "Exception was unhandled by user code" being thrown when I run this which is stopping the application. If I step through the code I see that and then it will go to the catch block. But, I would expect the catch block to handle this and not see the unhandled exception that is stopping the application?
Any suggestions appreciated.
class Program
{
static void Main(string[] args)
{
Action myMethod = new Action(Program.FooOneSecond);
Go("Go Method");
IAsyncResult tag =
myMethod.BeginInvoke(null, "passing some state");
try
{
myMethod.EndInvoke(tag);
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
string strState = (string)tag.AsyncState;
Console.WriteLine("State When Calling EndInvoke: "
+ tag.AsyncState.ToString());
Console.Read();
}
static int Work(string s) { return s.Length; throw null; }
static void Go(string s)
{
Console.WriteLine(s);
}
static void FooOneSecond()
{
// sleep for one second!
Thread.Sleep(1000);
// throw an exception
throw new Exception("Exception from FooOneSecond");
}
}
I just ran your code and the exception gets caught every time...