Is there an event that will tell me whether a currently running thread is being aborted mid-way not because the user called Abort
but because the program is terminating?
I need this for every thread shutting down along with information about the thread Id.
I was hoping it will be the AppDomainUnload
event but the documentation says nilch about it.
This page on the MSDN says:
When the runtime stops a background thread because the process is shutting down, no exception is thrown in the thread. However, when threads are stopped because the AppDomain.Unload method unloads the application domain, a ThreadAbortException is thrown in both foreground and background threads.
To test the fact, I wrote this little program that spawns two long-running threads, one of which is a foreground thread while the other a background thread, and immediately proceeds to exit the current process, thereby attempting to unload the current appdomain.
This should have called not only the DomainUnload
handler but also attempted to abort the two running threads and sent them a ThreadAbortException
.
But none of that happens.
The Output window displays the following output:
[#10] [Foreground]Starting to do stuff.
The thread 0x183c has exited with code 0 (0x0).
[#9] [Worker]Starting to do stuff.
[#10] [Foreground]Slept for 5 seconds. Now finishing up the doing of stuff.
The thread 0x2954 has exited with code 0 (0x0).
The program '[11224] KnowAboutDyingThread.vshost.exe' has exited with code 0 (0x0).
Here is my code:
using System;
using System.Diagnostics;
using System.Threading;
namespace KnowAboutDyingThread
{
// Source: https://msdn.microsoft.com/en-us/library/h339syd0%28v=vs.110%29.aspx
// When the runtime stops a background thread because the process is shutting down,
// no exception is thrown in the thread. However, when threads are stopped because the
// AppDomain.Unload method unloads the application domain, a ThreadAbortException is
// thrown in both foreground and background threads.
// I am trying that out
// I asked a question here about it: http://stackoverflow.com/questions/37552668/is-there-a-way-to-know-if-a-thread-is-being-aborted-because-the-program-is-termi
// Permalink: http://stackoverflow.com/q/37552668/303685
class Program
{
static void Main(string[] args)
{
AppDomain.CurrentDomain.DomainUnload += CurrentDomain_DomainUnload;
ThreadPool.QueueUserWorkItem(Do);
var t = new Thread(Do);
t.Name = "Foreground";
t.Start();
Process.GetCurrentProcess().Close();
}
private static void CurrentDomain_DomainUnload(object sender, EventArgs e)
{
Debug.Print("Unloading current appdomain...");
}
static void Do(object state)
{
try
{
Debug.Print(string.Format($"[#{Thread.CurrentThread.ManagedThreadId}] [{Thread.CurrentThread.Name ?? "Worker"}]Starting to do stuff."));
Thread.Sleep(5000);
Debug.Print(string.Format($"[#{Thread.CurrentThread.ManagedThreadId}] [{Thread.CurrentThread.Name ?? "Worker"}]Slept for 5 seconds. Now finishing up the doing of stuff."));
}
catch(ThreadAbortException abort)
{
Debug.Print(string.Format($"[#{Thread.CurrentThread.ManagedThreadId}] [{Thread.CurrentThread.Name ?? "Worker"}]Do got ThreadAbortException: {abort.GetType().Name}: {abort.Message}"));
}
catch(Exception ex)
{
Debug.Print(string.Format($"[#{Thread.CurrentThread.ManagedThreadId}] [{Thread.CurrentThread.Name ?? "Worker"}]Do had an exception: {ex.GetType().Name}: {ex.Message}"));
}
}
}
}
[1]: https://msdn.microsoft.com/en-us/library/system.appdomain.domainunload%28v=vs.110%29.aspx