Thread abort exception in WPF - c#

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.

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!
}
}

Kill a thread without affecting current thread

Everyone knows thread should exit gracefully, but now I have to kill a thread.
When there is a request comming, I start a thread as below
_thread = new Thread(ProcessTemplate);
_thread.Start();
In the ProcessTemplate method, it takes use of Google V8 to compile and run a javascript code sent from client-side.
The problem is, the javascript sent from client-side could be buggy and cause an infinite loop.
Hence, I count the time since the thread start and if the javasctript execution time exceeds 10 second, I kill the thread like
try
{
_thread.Abort();
}
catch
{
}
It works but also affects the current thread which started the _thread.
I receive "Thread was being aborted." exception from current thread.
how to avoid/ignore the exception?
I receive "Thread was being aborted." exception from current thread.
You receive this exception in the background thread, not in the main thread that started it as the documentation explains:
Raises a ThreadAbortException in the thread on which it is invoked, to
begin the process of terminating the thread. Calling this method
usually terminates the thread.
So inside this background thread you can handle this exception:
_thread = new Thread(() =>
{
try
{
ProcessTemplate();
}
catch (ThreadAbortException ex)
{
// the thread was aborted, call ResetAbort to
// avoid rethrowing the exception
Thread.ResetAbort();
}
);
Probably you are seeing the main thread affected because in certain cases unhandled exceptions in background threads could bring the AppDomain down. So normally you should handle those exceptions.
You can use a Task and pass it a CancellationToken
Link
I receive "Thread was being aborted." exception from current thread.
Because that's what happens when you call Thread.Abort:
When this method is invoked on a thread, the system throws a
ThreadAbortException in the thread to abort it. ThreadAbortException
is a special exception that can be caught by application code, but is
re-thrown at the end of the catch block unless ResetAbort is called.
You should catch the ThreadAbortException in your background thread and make sure its handled.
I would suggest that instead of using the rather dangerous abort, use the new features of the Task Parallel Library that allow for cooperative cancellations:
var cts = new CancellationTokenSource();
var ct = cts.Token;
var javaScriptTask = await Task.Run(() => ProcessTemplate, cts.Token);
And inside ProcessTemplate, monitor that CancellationToken:
ct.ThrowIfCancellationRequest();
Or, if you really want full control when making blocking calls, you should spin a new process to run your tasks.

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

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.

Task and exception silence

Why exceptions thrown within a task are silent exception and you never know if a certain exception has been thrown
try
{
Task task = new Task(
() => {
throw null;
}
);
task.Start();
}
catch
{
Console.WriteLine("Exception");
}
the program run successfully in a complete silence!
where the behavior of threads is different
try
{
Thread thread = new Thread(
() => {
throw null;
}
);
thread .Start();
}
catch
{
Console.WriteLine("Exception");
}
a null pointer exception will be thrown in this case.
What is the difference?
The behaviour of that scenario depends on what framework you have; in 4.0, you actually need to be careful - if you don't handle TaskScheduler.UnobservedTaskException, it will error later when it gets collected/finalized, and will kill your process.
TaskScheduler.UnobservedTaskException += (sender, args) =>
{
Trace.WriteLine(args.Exception.Message); // somebody forgot to check!
args.SetObserved();
};
This changes in 4.5, IIRC.
To check the outcome of a Task that might fail, you could register a continuation - i.e. call ContinueWith and check the result's exception. Alternatively, accessing the .Result of the task (which would also do an implicit Wait()) will re-surface the exception that happened. It is good to observe the result of a task, as that clears the finalization flag, meaning it can be collected more cheaply.
No, tasks are not threads. Tasks represent a high level abstraction - they are a unit of work that is inherently parallelisable. Threads run units of work.
In your first example, you create a unit of work and then tell it to run itself (how it does so is an implementation detail of Task). Whereas in your second example you explicitly schedule a unit of work (it would appear in a different manner to the implementation of Task).
The following assumes .NET 4.0, and the using the default TaskScheduler.
First of all notice that the exceptions are raised inside the delegates you pass, so they are raised in a different thread, not in the one you (logically) are doing your catch. So somehow the exception must be propagated from the thread that executes your delegate / lambda code to the one that started the thread/task.
Note that for Task, I think that the library can also choose not to run it on it's own thread, but rather on the calling thread (but I'm not sure if that was only true for Parallel.ForEach, etc. and not for a "naked" Task object).
For that two happen, two things must be fulfilled:
The calling thread is still active. Otherwise there is nothing left that could actually perform the catch.
The exception that was caused in the thread/task must somehow be preserved and reraised for you to catch it.
Having that said, both of your examples don't wait for the thread/task to finish. In the first example you're missing a task.Wait() (or similar) and in the second a thread.Join(). Depending on your test codes timing behavior this may mean that you may never be able to observe the exception from the thread/task (item 1 above).
Even if you add the two calls this is what happens for me (again .NET 4.0):
Task example: the call to task.Wait() actually reraises the exception originally left unhandled in the task's delegate (this is what the TPL will do for you internally), it does wrap it inside a System.AggregateException, which you could/would see if you'd use something more precise then a flat "catch-all".
Thread example: the exception raised by the delegate remains unhandled and your application exits (unless you do anything to deal with unhandled exceptions differently)
In other words I would have the examples as follows:
// Thread example
var thread = new Thread(() => { throw null; });
thread.Start();
thread.Join();
// Should never reach here, depending on timing sometimes not even
// until the Join() call. The process terminates as soon as the other
// thread runs the "throw null" code - which can logically happen somewhere
// after the "start" of the "Start()" call.
// Task example
try
{
var task = new Task(() => { throw null; });
task.Start();
task.Wait();
}
catch (AggregateException ex)
{
Console.WriteLine("Exception: " + ex);
}
I think you are not getting exception in case of Task because you are not waiting for exception in the main thread. You are just continuing. Put task.Wait() and you will get the exception in main thread.

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