views:

31

answers:

4

I have a thread that get I initialize like this:

Utility.Log("1");

myThread = new Thread(new ThreadStart(delegate
{
    Utility.Log("2");

and then the rest of the thread's execution. The weird thing is, despite that whole thing being wrapped in a try/catch, I'm only seeing a 1 in my log file (no 2), and I'm getting an unhandled System.IO.FileLoadException. I've tried also wrapping the entire body of the delegate in a try/catch, but I'm still getting that exception, and the Event Viewer is saying that the top most method of the exception is that method. It's very bizarre.

Any ideas of how I can track this down, or at least to properly catch the exception?

+1  A: 

You did only post a part of your code, therefore it's quite impossible to answer your question. So here's a general advice.

Never use anonymous methods for threads. It's very easy to do something wrong and uncaught exceptions in threads can bring your whole application down.

public void MyMethod()
{
    _myThread = new Thread(WorkerThread);
    _myThread.Start();
}

public void WorkerThread(object state)
{
    try
    {
      Utility.Log("2");
    }
    catch (Exception e)
    {
       //log error
    }
}
jgauffin
+1  A: 

The original try..catch will not definitely catch exceptions in your new thread, only in the originating thread.

If you want to work out what's going on in the child thread, you'll have to give it its own exception handling. It sounds like you tried to do this per "I've tried also wrapping the entire body of the delegate in a try/catch", but that altered code would be needed to confirm its correctness.

You should also be able to narrow this down by debugging into the child thread.

Steve Townsend
+1  A: 

You need add a thread exception event handler:

Just add the handler before application.run and you can catch all unhandled thread exceptions.

Source from msdn:

[SecurityPermission(SecurityAction.Demand, Flags = SecurityPermissionFlag.ControlAppDomain)]
public static void Main(string[] args)
{
    // Add the event handler for handling UI thread exceptions to the event.
    Application.ThreadException += new ThreadExceptionEventHandler(ErrorHandlerForm.Form1_UIThreadException);

    // Set the unhandled exception mode to force all Windows Forms errors to go through
    // our handler.
    Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);

    // Add the event handler for handling non-UI thread exceptions to the event. 
    AppDomain.CurrentDomain.UnhandledException +=
        new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);

    // Runs the application.
    Application.Run(new ErrorHandlerForm());
}

http://msdn.microsoft.com/en-us/library/system.windows.forms.application.threadexception.aspx

honibis
+1  A: 

A FileLoadException is a pretty serious mishap. It is raised when the JIT compiler tries to compile the code that you run in your thread. A try/catch pair cannot catch this exception because it is raised before the code starts executing. In other words, it bombs before you enter the try block. Given that this is a thread, you can't stop your program from crashing to the desktop. The last gasp you have is AppDomain.UnhandledException, the e.ExceptionObject's InnerException property tells you what is really going wrong.

This exception should otherwise always be easily fixable. It is a configuration issue, the JIT compiler finds an assembly that has the wrong version number or is an old version of the assembly, something like that. If you can't diagnose it from AppDomain.UnhandledException then the Fuslogvw.exe tool can show you how it is finding the wrong assembly. A full rebuild of your solution ought to be halfway to a fix.

Hans Passant