Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Expected ThreadAbort for Background Thread

I have the following.

public static Thread testThread = new Thread(ThreadStart) {Name = "TestThread", IsBackground = true};
private void Form_Load()
{
    testThread.Start()
}
private static void ThreadStart()
{
    int count = 0;
    try
    {
        while (true)
        {
            count++;
        }
    }
    catch (Exception ex)
    {

        StreamWriter stream = new StreamWriter(File.OpenWrite("Exception.txt"));
        stream.WriteLine(count + "\n" + ex);
        stream.Flush();
        stream.Close();
    }
}

When I call Thread.Abort() I catch the exception and write out to the file. However, if I instead close the application nothing is written. I also have

AppDomain.CurrentDomain.UnhandledException +=
   new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
Application.SetUnhandledExceptionMode(UnhandledExceptionMode.ThrowException);
Application.ThreadException +=
   new System.Threading.ThreadExceptionEventHandler(Application_ThreadException);

But it doesn't appear an exception is ever thrown.

I suppose adding a question is prudent.

What happens to a running background thread when the parent processes exits? My understanding was a ThreadAbortException is thrown to exit the thread. If this is the case, how can the ThreadAbortException be caught in order to clean up resources that may be present in the thread?

like image 318
galford13x Avatar asked Feb 05 '12 20:02

galford13x


1 Answers

First of all, the application probably isn't exiting, because you are not making these into background threads. My guess is that Task Manager will show copies of your EXE running unexpectedly. You need to set Thread.IsBackground to true on the thread object before calling Start.

Secondly, the behavior that you expect is explicitly debunked by the documentation:

Note

When the common language runtime (CLR) stops background threads, after all foreground threads in a managed executable have ended, it does not use System.Threading.Thread.Abort. Therefore, you cannot use ThreadAbortException to detect when background threads are being terminated by the CLR.

EDIT:

When a process is exiting, there is no need to clean up resources held by the worker threads because, you know, the process is exiting. The contract with regard to background threads is that they can be killed at any time when the process exits. Therefore, if your background threads are doing something that requires transactional correctness, they probably should not be background threads. Make 'em foreground threads and have them periodically check or wait on a reset event to see whether they should exit and allow the process to end.

like image 83
Chris Shain Avatar answered Oct 09 '22 14:10

Chris Shain