Some.NET on multithreaded exception handling tips to share

  • 2020-05-09 18:26:55
  • OfStack

Multithreaded environment
In our product SE, there are two main types of multithreading: one is initiated by ThreadPool or new Thread, and the other is Socket communication callback.
Multithreaded exception catching
For exception handling like 1, we simply include error-prone statements in try/catch statements. I have also applied this method to multithreaded exception catching, but the result is not so. The code is as follows:

 
public static void Main() 
{ 
    try 
    { 
        new Thread (Go).Start(); 
    } 
    catch (Exception ex) 
    { 
        //  Never execute here!  
        Console.WriteLine ("Exception!"); 
    } 
} 
private static void Go() 
{ 
    throw null; 
} 

The correct thing to do is to catch the exception in the new thread entry method Go:
 
public static void Main() 
{ 
    new Thread (Go).Start(); 
} 
private static void Go() 
{ 
    try 
    { 
        ... 
        throw null; //  The exception will be caught  
        ... 
    } 
    catch (Exception ex) 
    { 
        //  Exception logging, or notifying another thread that an exception has occurred  
        ... 
    } 
} 

The correct answer comes from the section Exception Handling in Threading in C#, which covers all aspects of.NET multithreading. It's the best article I've ever seen.

Once we've found the right way to catch multithreaded exceptions, it's natural to wonder: does every thread entry method have to do this?

See also the description in section Exception Handling in Threading in C# : starting with.NET 2.0, an unhandled exception on any one thread can cause the entire application to shut down. Therefore, the try/catch statement must be used in every thread entry method, at least in a production application, to prevent the application from shutting down the entire application because of unexpected code.

If you just write down the exception information and don't care about the application closing exception, there are two ways to do this:

  1. For the Windows Form program, there is a global exception handling event: Application.ThreadException;

  2. For all.NET programs, there is a lower level global exception handling event: AppDomain.UnhandledException;
Higher requirements
We can simply log errors with global exception handling events; Exceptions can also be caught and logged in each thread entry method if the application is not interrupted. Is there a way to catch exceptions without interrupting the application, and to catch exceptions as easily as global exception handling events?
For actively creating a new thread, you can at least do this:

 
public static class ThreadExecutor 
{ 
    public static bool Execute(System.Threading.WaitCallback callback, object state) 
    { 
        try 
        { 
            return System.Threading.ThreadPool.QueueUserWorkItem(callback, state); 
        } 
        catch (Exception e) 
        { 
            // log the exception 
        } 
        return false; 
    } 
} 


Related articles: