C# - Thread Abort Exception (Thread Abort Exception) rethrowing itself - c#

I have the current code:
class Program
{
private static void Main()
{
while (true)
{
try
{
Thread.CurrentThread.Abort();
}
catch (ThreadAbortException)
{
Console.WriteLine("Abort!");
Thread.ResetAbort();
}
Console.WriteLine("now waiting");
Console.ReadKey();
}
}
}
Now I know the method ResetAbort is supposed to prevent the ThreadAbortException from continue to re-throw itself even when a catch statement is catching it, but my question is this:
If anyone can use the ResetAbort method, then what's the point of the exception specially re-throw itself?
the user can just do
catch (ThreadAbortException ex)
{
Console.WriteLine("Abort!");
throw ex;
}

Thread.ResetAbort() is not meant for common use. It can cause undesired behavior if you don't understand why the thead abort happened. Because of this, and probably to make ASP.NETs stable in shared hosting environments, the SecurityPermissionFlag.ControlThread permission is required to call Thread.ResetAbort()
MSDN Link

The point of ThreadAbortException rethrowing itself is to make sure the thread terminates unless the user explicitly calls ResetAbort.
Let me explain:
try
{
// ... Thread abort happens somewhere in here
}
catch (Exception ex)
{
_log.Error(ex);
}
Here you have a typical example of code that ensures no exception propagates from inside the try block. I know that catching Exception is bad practice, but code like this exists nonetheless.
If you call Abort while the thread is inside the try block you still want it to abort. You just can't rely on users writing this sort of code everywhere:
try
{
// ... Thread abort happens somewhere in here
}
catch (ThreadAbortException)
{
throw; // No, you'll NEVER see code like this in real life
}
catch (Exception ex)
{
_log.Error(ex);
}
So, in order to provide a sort of reliable Abort, the exception has to be automatically rethrown, or it may easily get discarded by accident.
ResetAbort is meant for the very rare case when you specifically detect a thread abort, and you exactly know why it happenned, and you want to prevent it.
Needless to say, the use cases for this are extremely rare. Thread aborts are treated by the runtime in a very special way, and you should avoid them whenever possible. Heck, they even aren't reliable as you pointed out, and all this discussion is ignoring CERs which make matters worse.

The point is to define a default behavior in which the exception is rethrown, seeing as how there is a remote chance that the user will have any point of continuing the thread.
Moreover, ResetAbort has a security demand and can not be called by any code.

Because Aborting a thread doesn't necessarily mean an exception will be thrown. For the Abort Procedure the catch (ThreadAbortException) block is just another critical region of code. It only gives us a thread safe and convenient way of detecting if the current thread is being aborted (and maybe with some state being passed too) in case we want to do something special. Other than that, it is like any other critical region (like a finally block) where it will terminate the thread after its execution.
At the same time, in your example Abort is called synchronously (which is actually safe to do) and in that case it is very similar to throwing an exception. Things only get interesting and dangerous when it's called asynchronously from another thread, due to the Abort procedure being more complicated than just throwing an exception: In essence, first, thread is marked as being aborted, then critical code regions (for example finally blocks) are executed and only then the exception is thrown, if the AbortRequested flag is still set on the thread, and so on.
Code below illustrates this fact by recovering an aborted thread without catching any exceptions:
var inFinally = new ManualResetEvent(false);
var abortCalled = new ManualResetEvent(false);
var t = new Thread(_ =>
{
Console.WriteLine("Thread started..");
try
{
}
finally
{
inFinally.Set();
abortCalled.WaitOne();
Console.WriteLine(" ThreadState (before): " + Thread.CurrentThread.ThreadState);
// This isn't thread safe, and ugly?
if ((Thread.CurrentThread.ThreadState & ThreadState.AbortRequested) != 0)
{
Thread.ResetAbort();
}
Console.WriteLine(" ThreadState (after): " + Thread.CurrentThread.ThreadState);
}
Console.WriteLine("Executed because we called Thread.ResetAbort()");
});
t.Start();
inFinally.WaitOne();
// Call from another thread because Abort()
// blocks while in finally block
ThreadPool.QueueUserWorkItem(_ => t.Abort());
while ((t.ThreadState & ThreadState.AbortRequested) == 0)
{
Thread.Sleep(1);
}
abortCalled.Set();
Console.ReadLine();
// Output:
//--------------------------------------------------
// Thread started..
// ThreadState (before): AbortRequested
// ThreadState (after): Running
// Executed because we called Thread.ResetAbort()
Now, I must be honest: I am not entirely sure how one could use this feature and create something useful. But it sounds like Thread.Abort API was (probably still is, I don't know) used to facilitate thread and AppDomain reuse in frameworks like ASP.NET.
In one of Joe Duffy's Blog entries, Managed code and asynchronous exception hardening, he talks about ResetAbort and the Abort API:
Some framework infrastructure, most notably ASP.NET, even aborts individual threads
routinely without unloading the domain. They backstop the ThreadAbortExceptions, call
ResetAbort on the thread and reuse it or return it to the CLR ThreadPool.
I can imagine it can be used in a framework to reuse the managed threads, reducing the overhead. However, the problems (bad thread synchronization design, bad exception handling, dead locks and so on) introduced in user code, by this easily misunderstood API, rendered the Abort and ResetAbort calls more troublesome than useful.

Related

Why is it not possible to directly catch and handle an exception thrown from a worker thread in the Main thread?

I am reading multithreading in Albahari's c# in a nutshell. He says that if a thread (for example Main thread) creates and starts a worker thread , then an exception thrown by the worker thread cannot directly be caught and handled by the creating thread. Let me quote him verbatim:
"Any try / catch / finally blocks in effect when a thread is created are of no
relevance to the thread when it starts executing. Consider the following
program:
public static void Main()
{
try
{
Thread workerThread = new Thread (Go);
workerThread.Start();
}
catch (Exception ex)
{
// We'll never get here!
Console.WriteLine ("Exception!");
}
}
static void Go()
{
throw null; // Throws a NullReferenceException
}
Albahari goes on to say that:
"The try / catch statement in this example is ineffective, and the newly
created thread will be encumbered with an unhandled
NullReferenceException . This behavior makes sense when you consider
that each thread has an independent execution path."
So here is the crux of my question:
I don't get the relevance of "each thread has an independent execution path". I mean why should it matter if the execution paths are independent ? I mean when the workerThread throws an unhandled exception -- why can't the CLR just halt the Main thread and hand over the exception object to the catch block in the Main? What's stopping it ??
[NOTES:
The other related question How do I handle exceptions from worker threads and main thread in a single catch block? is NOT asking the same question --- and none of the elaborate answers express WHY can't the CLR marshal an unhandled exception from a worker thread to the Main thread
Similar question is asked about another language , C++, -- where the answers suggest that it has something to do with the two threads having different stacks and the logical impossibility of mixing the two while unwinding the stack during exception handling. I'm not sure whether those answers apply here to a managed execution environment , like that of c#.
]
The main thread might have already finished executing.
I know it is hard to understand at first, but the worker thread is not executed like a method call even if it looks like that. The thread is created inside that try-block, but the execution might happen much later or not at all. Source code in text form can not make this visible. There seems to be some kind of "spacial" proximity of the try-block and the thread, but the moment the thread is created, the spacial proximity is gone. The try block only handles any exceptions that happen while the thread is created, but the it is "detached" from it.
Analogy: The main thread is the manager (team lead) and the worker thread(s) are the workers (team members) reporting to that manager. The workers are working in their home office. In the morning the manager is sending them emails with tasks for the day ("execute method Go"). Since the manager can not see the workers doing their work, she can only notice any progress or lack of it, if the workers send progress reports from time to time. If workers fall off their chairs or down the stairs (exceptions), the manager would not know. The workers need to make sure to catch such exceptions and send an appropriate message to the manager to let her know. The manager is (in this case) not waiting around after sending the initial emails, but is doing other work in the meantime.
You are asking why the CLR can't halt the Main thread, and handle the exception of the child thread. Do you mean the main thread should always suspend execution automatically, immediately after launching a new Thread? This would be very unhelpful, since a program could then have at a maximum one and only one active thread. It would be the end of multithreading as we know it! So you probably mean that the CLR should offer a mechanism to do this suspension of execution on demand. Although such a mechanism is indeed not available, you can do something very close to it using tasks:
public static void Main()
{
try
{
Task workerTask = new Task(() =>
{
throw null;
}, TaskCreationOptions.LongRunning); // Use a dedicated thread
workerTask.Start();
workerTask.Wait();
}
catch (Exception ex)
{
Console.WriteLine("Exception!"); // It happens!
}
}

Thread abort exception in WPF

I am trying to implement loaders in my WPF application. During some heavy operations, the UI thread gets frozen, so I had to implement the loaders using threads. Each time the loader loads, a new thread is created and this thread gets aborted (manually) when the loader sets off. The problem I am facing is that sometimes the application gets crashed giving a ThreadAbortException.
This is the code to start the loader :
try
{
//if(newWindowThread !=null && !newWindowThread.IsAlive) { }
newWindowThread = new Thread(new ThreadStart(() =>
{
try
{
// Create and show the Window
awq = new BusyIndicatorDisguise(BusyMessage);
awq.Show(); // <== POINT WHERE THE EXCEPTION IS THROWN
//Start the Dispatcher Processing
if (!isDispatcherStarted)
{
var a = Thread.CurrentThread;
var b = Dispatcher.CurrentDispatcher;
//isDispatcherStarted = true;
Dispatcher.Run();
}
}
catch (ThreadAbortException thEx)
{
}
catch (Exception ex)
{
}
}
));
// Set the apartment state
newWindowThread.SetApartmentState(ApartmentState.STA);
// Make the thread a background thread
newWindowThread.IsBackground = true;
// Start the thread
newWindowThread.Start();
}
catch (Exception ex)
{
}
This code is for stopping the loader :
if (newWindowThread != null && newWindowThread.IsAlive)
{
newWindowThread.Abort();
}
I am not able to catch this exception in my catch block. Maybe because it is on a different thread.
I want to know how can I avoid the ThreadAbortException
You should add a try catch block in the thread that may throw the exception and manage it accordingly to your needs.
Anyway, as #Josh says in other similar post
There are much better ways of aborting a thread without
using Thread.Abort which not only chaotically interrupts your code at
an unpredictable point, it's also not guaranteed to work because if
your thread is currently calling out to some unmanaged code, the
thread will not abort until control returns to managed code.
It's much better to use some type of synchronization primitive such as
aManualResetEvent to act as a flag telling your thread when to exit.
You could even use a boolean field for this purpose which is what the
BackgroundWorker does.
If you throw an exception for yourself, forget the Thread.Abort. That's why:
Throwing an exception is an extremely costly operation. It saves the whole call stack and other useful data for debugging. In this case all you need is just to set a simple flag.
ThreadAbortException is a tricky one. It is automatically re-thrown at the end of the exception handler block unless you call Thread.ResetAbort in the catch block. But do NOT do that!
A ThreadAbortException is an asynchronous exception that means it can occur at any point of your code, which may cause unpredictable results. It is a brute force tool such as the End task button in the Task Manager. Use it only if you cannot rewrite the executed code (3rd party component) and if you are sure that you can unload the remains of the unstable execution environment (it is executed in an AppDomain).
Instead, send a cancellation request to your loader (can be a simple bool), which you should poll regularly during the load operation. Here is an example how you can do it by using a BackgroundWorker and a volatile field.

call method from another thread without blocking the thread (or write custom SynchronizationContext for non-UI thread) C#

This is probably one of the most frequent questions in the Stackoverflow, however I couldn't find the exact answer to my question:
I would like to design a pattern, which allows to start thread B from thread A and under specific condition (for example when exception occurs) call the method in thread A. In case of exception the correct thread matters a lot because the exception must call a catch method in the main thread A. If a thread A is an UI thread then everything is simple (call .Invoke() or .BeginInvoke() and that's it). The UI thread has some mechanism how it is done and I would like to get some insights how it would be possible to write my own mechanism for the non-UI thread. The commonly suggested method to achieve this is using the message pumping http://www.codeproject.com/Articles/32113/Understanding-SynchronizationContext-Part-II
but the while loop would block the thread A and this is not what I need and not the way how UI thread handles this issue. There are multiple ways to work around this issue but I would like to get a deeper understanding of the issue and write my own generic utility independently of the chosen methods like using System.Threading.Thread or System.Threading.Tasks.Task or BackgroundWorker or anything else and independently if there is a UI thread or not (e.g. Console application).
Below is the example code, which I try to use for testing the catching of the exception (which clearly indicates the wrong thread an exception is thrown to). I will use it as an utility with all the locking features, checking if a thread is running, etc. that is why I create an instance of a class.
class Program
{
static void Main(string[] args)
{
CustomThreads t = new CustomThreads();
try
{
// finally is called after the first action
t.RunCustomTask(ForceException, ThrowException); // Runs the ForceException and in a catch calls the ThrowException
// finally is never reached due to the unhandled Exception
t.RunCustomThread(ForceException, ThrowException);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
// well, this is a lie but it is just an indication that thread B was called
Console.WriteLine("DONE, press any key");
Console.ReadKey();
}
private static void ThrowException(Exception ex)
{
throw new Exception(ex.Message, ex);
}
static void ForceException()
{
throw new Exception("Exception thrown");
}
}
public class CustomThreads
{
public void RunCustomTask(Action action, Action<Exception> action_on_exception)
{
Task.Factory.StartNew(() => PerformAction(action, action_on_exception));
}
public void RunCustomThread(Action action, Action<Exception> action_on_exception)
{
new Thread(() => PerformAction(action, action_on_exception)).Start();
}
private void PerformAction(Action action, Action<Exception> action_on_exception)
{
try
{
action();
}
catch (Exception ex)
{
action_on_exception.Invoke(ex);
}
finally
{
Console.WriteLine("Finally is called");
}
}
}
One more interesting feature that I've found is that new Thread() throws unhandled Exception and finally is never called whereas new Task() does not, and finally is called. Maybe someone could comment on the reason of this difference.
and not the way how UI thread handles this issue
That is not accurate, it is exactly how a UI thread handles it. The message loop is the general solution to the producer-consumer problem. Where in a typical Windows program, the operating system as well as other processes produce messages and the one-and-only UI thread consumes.
This pattern is required to deal with code that is fundamentally thread-unsafe. And there always is a lot of unsafe code around, the more convoluted it gets the lower the odds that it can be made thread-safe. Something you can see in .NET, there are very few classes that are thread-safe by design. Something as simple is a List<> is not thread-safe and it up to you to use the lock keyword to keep it safe. GUI code is drastically non-safe and no amount of locking is going to make it safe.
Not just because it is hard to figure out where to put the lock statement, there is a bunch of code involved that you did not write. Like message hooks, UI automation, programs that put objects on the clipboard that you paste, drag and drop, shell extensions that run when you use a shell dialog like OpenFileDialog. All of that code is thread-unsafe, primarily because its author did not have to make it thread-safe. If you trip a threading bug in such code then you do not have a phone number to call and a completely unsolvable problem.
Making a method call run on a specific thread requires this kind of help. It is not possible to arbitrarily interrupt the thread from whatever it is doing and force it to call a method. That causes horrible and completely undebuggable re-entrancy problems. Like the kind of problems caused by DoEvents(), but multiplied by a thousand. When code enters the dispatcher loop then it is implicitly "idle" and not busy executing its own code. So can take an execution request from the message queue. This can still go wrong, you'll shoot your leg off when you pump when you are not idle. Which is why DoEvents() is so dangerous.
So no shortcuts here, you really do need to deal with that while() loop. That it is possible to do so is something you have pretty solid proof for, the UI thread does it pretty well. Consider creating your own.

c# try...catch statement doesn't capture exception when exception occurred in asynchronous operation

for example:
first step:bind UnhandledException event.
AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
second step:
try
{
//at here,do asynchronous operation and throw a exception.
}
catch (Exception ex)
{
Console.WriteLine("error");
}
when the asynchronous operation throw a exception,the catch code it not called,just only the UnhandledException event is triggered,after end event called then exit application.
i want capture exception anything in catch statement and avoid exit application.
=======================================================
the asynchronous code is the asynchronous socket operation.in the socket asynchronous receive message event(BeginReceive,EndReceive),i throw a OverFlowException.
throw new OverflowException("chunk size too long.");
=============================================
you are right,now i capture the exception in asynchronous operation and passed it to original class(this means exception will throw on the same thread,that can try...catcy statement can was called)
An asynchronous task by default will operate in a different context from the one it was instantiated in. The try/catch block is therefore not effective in this case.
Think about it in the following way.
Worker worker = new HouseMaid();
try
{
worker.DoSomeWork();
}
catch(WorkerIsSickException ex)
{
worker.TakeMedicin();
worker.StopWorkingAndRestForAWhile();
}
Here we see that when the worker gets sick, the work process breaks and the exception will be handeled. However, when we do:
Worker worker = new HouseMaid();
try
{
Worker otherWorker = new HouseMaidHelper();
worker.DelegateWorkTo(otherWorker, CallBackWhenOTherWorkerIsDone);
worker.GoOnDoSomethingElse();
}
catch(WorkerIsSickException ex)
{
worker.TakeMedicin();
worker.StopWorkingAndRestForAWhile();
}
The work try/catch block (or safety net if you will), will only apply for the worker, not otherWorker. The otherWorker has its own scope to work in. If the other worker fails, that shouldnt mean that the worker has to take the medicine.
Your question isn't clear, but if it's the asynchronous operation which throws the exception, then the code you've shown could easily have completed before the exception is thrown anyway - it's all asynchronous, right?
Basically asynchrony makes you rethink error handling - and quite how you do it depends on your asynchrony approach. You'd often catch the exception in the callback - or not even catch it, but check for it with something like Task.Status.
Admittedly all the work in C# 5 for async stuff should make some of this easier, but you still need to think about the asynchrony.
The asynchronous operation will get started successfully, hence execution will continue successfully and miss your exception handler. If you want to catch the exception within the asynchronous operation, you will need exception handling in the code that is executing asynchronously. You could then put a call back to a function in your original class if you want to handle the exception there.

Benefits of Thread.ResetAbort

When a thread is canceled via Thread.Abort(), a ThreadAbortException is thrown inside the Thread on which Thread.Abort() was called on. This leads the thread to immediately stop its work and the exception bubbles up the call stack until it leaves the thread's main method. This causes the thread to be aborted.
What are the benefits of an ExceptionHandler for the ThreadAbortException in the threads main method where Thread.ResetAbort() is called, when the thread terminates itself anyway after the catch block due to stepping out its main method?
private void ThreadMainMethod( )
{
try
{
while(runningAllowed = true)
{
//Do some work here
}
}
catch ( ThreadAbortException )
{
Thread.ResetAbort( );
}
}
One scenario I can think of is that you want to take down the thread in a controlled manner. Let's say you have a worker thread that is polling some resource. If the application's main thread invokes Abort on the worker thread, a ThreadAbortException is thrown. You can then catch that exception in start method for the worker thread, call ResetAbort and then finish the method by releasing resource, closing open files/connections and so on:
public void ThreadStarter()
{
try
{
RunWorkerLoop();
}
catch (ThreadAbortException)
{
Thread.ResetAbort();
}
// clean up and end gracefully
}
Probably the only reason you'd do that would be if you were in a great position to decide whether or not you should actually abort.
So perhaps the thread would catch it, check the status of something, and then go back about its work again. Though this does imply that you're basically using the '.abort()' to control the flow of this thread. And that's quite a bad idea. You should communicate with it in another way.
In general, I would think there are not many cases where this is a good idea, and it wouldn't be the advice for any particular pattern or implementation I can think of.
In you particular case it doesn't really make a difference, because the thread will be terminated once the method is done running.
However, in other case you may have a method that runs in an endless loop. In this case, you can shutdown the thread using the ThreadAbortException (I am not saying that you should, but you could). If the thread for some reason determines to continue despite the exception it needs to call ResetAbort to prevent the runtime to automatically rethrow the ThreadAbortException.
I found that calling ResetAbort() to be of great help in this elegant implementation of the WaitFor with time-out pattern .

Categories

Resources