catch block not catching exception in another thread - c#

method A()
{
try
{
Thread t = new Thread(new ThreadStart(B));
t.Start();
}
catch(exception e)
{
//show message of exception
}
}
method B()
{
// getDBQuery
}
a exception in B but not catched.
does it legal in .net?

Correct, exceptions from a Thread are not forwarded to the caller, the Thread should handle this by itself.
The most general answer is that you should not be using a (bare) Thread here. It's not efficient and not convenient.
When you use a Task, the exception is stored and raised when you cal Wait() or Result.

When A is finished executing B might still be running as it is on an independent thread. For that reason it is impossible by principle for A to catch all exceptions that B produces.
Move the try-catch to inside of B. The Thread class does not forward exceptions.
Better yet, use Task which allows you to propagate and inspect exceptions.

Related

When we call Abort() method in Threading,and For conditions? Is there any validations to check before Abort the thread?

I'm getting ThreadAbortException when call Abort() method, and I referred to solve this in Stack Overflow that they said to use Thread.ResetAbort() method before ending the thread, but It's not clear to me.
Please suggest me where can I use ResetAbort method. I'm getting that exception in marked line when call the Abort() method.
while (true)
{
Group g = null;
if (countGroupsList != null)
{
lock (countGroupsList.SyncRoot) // Exception here
{
if (groupsCounter < countGroupsList.Count)
{
g = (Group)countGroupsList[groupsCounter];
groupsCounter++;
}
}
}
Thread.Abort is a rude way to kill a thread. But if you really want to do so you can just ignore the exception. It's the way the thread says: Ouch, I'm dying.
You also can catch this exception and use the Thread.Abort method in your catch block. But that will prevent the thread to be killed.

How can an exception bubble up beyond this task?

I thought this approach would be safe, in that it wouldn't allow exceptions to propagate. A colleague of mine suggested that the exceptions may need to be observed on the main thread, and should thus be passed up to the main thread. Is that the answer? Can you see how an exception could leak through this?
private static void InvokeProcessHandlers<T>(List<T> processHandlers, Action<T> action)
{
// Loop through process handlers asynchronously, giving them each their own chance to do their thing.
Task.Factory.StartNew(() =>
{
foreach (T handler in processHandlers)
{
try
{
action.Invoke(handler);
}
catch (Exception ex)
{
try
{
EventLog.WriteEntry(ResourceCommon.LogSource,
String.Format(CultureInfo.CurrentCulture, "An error occurred in a pre- or post-process interception handler: {0}", ex.ToString()),
EventLogEntryType.Error);
}
catch (Exception)
{
// Eat it. Nothing else we can do. Something is seriously broken.
}
continue; // Don't let one handler failure stop the rest from processing.
}
}
});
}
By the way, a stack trace is indeed showing that an exception is leaking from this method.
The exception is AccessViolation, and I believe it has to do with the code that calls this method:
InvokeProcessHandlers<IInterceptionPostProcessHandler>(InterceptionPostProcessHandlers, handler => handler.Process(methodCallMessage, methodReturnMessage));
The getter for InterceptionPostProcessHandlers contains this:
_interceptionPreprocessHandlers = ReflectionUtility.GetObjectsForAnInterface<IInterceptionPreprocessHandler>(Assembly.GetExecutingAssembly());
Just make sure to check parameter for null references before you iterate
other than that there is nothing wrong as log writing is not something to stop the execution, but i would recommend to make it more clean and maintainable by encapsulating the logging into a mothod like:
bool Logger.TryLog(params);
and inside this method do the try with a catch that returns false and if you want to handle it in client code do it and if you dont never mind just call the logger in a clean encapsulated way
A colleague of mine suggested that the exceptions may need to be
observed on the main thread, and should thus be passed up to the main
thread.
How can it be "passed up to the main thread"? The main thread is away and doing its own thing.
The best you can do is to make it configurable and accept an ExceptionHandler delegate that is called.

exception handling in the multi thread environment

I want to know if
try/catch can catch the exceptions thrown by the children threads.
if not, what's the best practice to handling exceptions thrown in the child thread.
You can listen to the Application.ThreadException and AppDomain.UnhandledException events to catch uncaught exceptions from thread. But the best is to catch and handle exceptions in the threads themselves. This should be a last resort for graceful shutdown / logging.
It depends on the .NET framework you're targeting.
In 1.1 and lesser, exceptions thrown by children threads will be forwarded to the main thread only if they run outside a try/catch block.
In 2.0 and later, this behaviour is changed: thread will be terminated and exceptions won't be allowed to proceed any further.
Anyway, you can handle exceptions inside a thread as you would do in a single-threaded application.
See http://msdn.microsoft.com/en-us/library/ms228965(v=VS.90).aspx for reference.
No, consider the following code:
try
{
var t = new Thread(()=>
{
Thread.Sleep(5000);
throw new Exception();
});
t.Start();
//t.Join();
}
catch
{
//you can't deal with exception here
//even though you uncomment `t.Join`
}
Deal with exceptions in the child thread which the exceptions "belongs" to.

What's the deal with the hidden Throw when catching a ThreadAbortException?

I'm going through a book of general c# development, and I've come to the thread abort section.
The book says something along the lines that when you call Thread.Abort() on another thread, that thread will throw a ThreadAbortException, and even if you tried to supress it it would automatically rethrow it, unless you did some bs that's generally frowned upon. Here's the simple example offered.
using System;
using System.Threading;
public class EntryPoint
{
private static void ThreadFunc()
{
ulong counter = 0;
while (true)
{
try
{
Console.WriteLine("{0}", counter++);
}
catch (ThreadAbortException)
{
// Attempt to swallow the exception and continue.
Console.WriteLine("Abort!");
}
}
}
static void Main()
{
try
{
Thread newThread = new Thread(new ThreadStart(EntryPoint.ThreadFunc));
newThread.Start();
Thread.Sleep(2000);
// Abort the thread.
newThread.Abort();
// Wait for thread to finish.
newThread.Join();
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
}
The book says:
When your thread finishes processing the abort exception, the runtime implicitly rethrows it at the end of your exception handler. It’s the same as if you had rethrown the exception yourself. Therefore, any outer exception handlers or finally blocks will still execute normally. In the example, the call to Join won’t be waiting forever as initially expected.
So i wrapped a try catch around the Thread.Abort() call and set a break point, expecting it to hit this, considering the text says "any outer exception handlers or finally blocks will still execute normally". BUT IT DOES NOT. I'm racking my brain to figure out why.
Anyone have any thoughts on why this isn't the case? Is the book wrong?
Thanks in advance.
The exception is thrown on the thread that is aborted. Once thrown an exception travels up the call stack of that thread, but it does not jump over to another thread, nor to the caller of Thread.Abort.
The claim was:
Therefore, any outer exception handlers or finally blocks will still execute normally.
A better test of this claim is the following code:
private static void ThreadFunc()
{
ulong counter = 0;
while (true)
{
try
{
try
{
Console.WriteLine("{0}", counter++);
}
catch (ThreadAbortException)
{
// Attempt to swallow the exception and continue.
Console.WriteLine("Abort!");
}
}
catch (ThreadAbortException)
{
Console.WriteLine("Do we get here?");
}
}
}
If ThreadAbortException were a normal type of exception we would not expect to hit the line "Do we get here?", but we do.
The Thread.Abort() doens't throw the exception. Rather, an exception is thrown in the thread, and even if you catch it, is is immediately rethrown. In your case, it would be rethrown right after it prints "Abort!". Go ahead and wrap the body of your thread method in another try/catch and you'll be able to confirm this.
You probably blinked your eyes too fast to see it. Modify your code like this:
// Wait for thread to finish.
newThread.Join();
Console.ReadLine();
Possible output:
....
8807
8808
Abort!
What that book should've said is that you should never use Thread.Abort because it has a massive amount of problems.
As such, any non-obvious or unexpected behaviour you see should be taken as an indication that you really should not use Thread.Abort.
The point of Thread.Abort is to signal to a thread that the application is terminating, you have failed to exit nicely (I have asked), and now you have to die. Sorry about that, but that's just the way it is.
That is all. Every other use-case you can think of that would involve Thread.Abort should have a different solution, period.
A cooperative method is usually the best way to do it. Use a signal (even something as simple as a volatile boolean field), and just set the signal when you want the thread to exit. Periodically check this signal in the other thread, and when set, exit. Or... even throw an exception if you detect the signal.
Just never impose that exception from the outside using Thread.Abort.
Now, having said that, if you really want to know how to handle this exception, you can signal to the runtime that you don't want the exception to automatically propagate up the stack (ThreadAbortException is a special case) by calling Thread.ResetAbort().
However, you should not do this.
When you start the thread, your code goes on and the thread you started is running separately i.e. why we shouldn't expect to hit that line in main.
using System;
using System.Threading;
public class EntryPoint
{
private static void ThreadFunc()
{
try
{
ulong counter = 0;
while (true)
{
try
{
Console.WriteLine("{0}", counter++);
}
catch (ThreadAbortException)
{
// Attempt to swallow the exception and continue.
Console.WriteLine("Abort!");
}
}
}
catch(ThreadAbortException)
{
Console.WriteLine("Certainly unstoppable!");
}
}
static void Main()
{
try
{
Thread newThread = new Thread(new ThreadStart(EntryPoint.ThreadFunc));
newThread.Start();
Thread.Sleep(2000);
// Abort the thread.
newThread.Abort();
// Wait for thread to finish.
newThread.Join();
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
}
Remember ThreadAbortException its a v. special exception, since for all purposes the thread is meant to be dead. That's fine when you are absolutely terminating your app and don't have anything special in the thread. When instead you want to gracefully terminate operations, don't use Thread.Abort, use a separate mecanism to tell the thread it needs to stop. Like in the example, setting a static member it checks in the while, the next cycle it knows it has to stop in a controlled place.

Is there a good method in C# for throwing an exception on a given thread

The code that I want to write is like this:
void MethodOnThreadA()
{
for (;;)
{
// Do stuff
if (ErrorConditionMet)
ThrowOnThread(threadB, new MyException(...));
}
}
void MethodOnThreadB()
{
try
{
for (;;)
{
// Do stuff
}
}
catch (MyException ex)
{
// Do the right thing for this exception.
}
}
I know I can have thread B periodically check, in thread safe way, to see if a flag has been set by thread A, but that makes the code more complicated. Is there a better mechanism that I can use?
Here is a more fleshed out example of periodically checking:
Dictionary<Thread, Exception> exceptionDictionary = new Dictionary<Thread, Exception>();
void ThrowOnThread(Thread thread, Exception ex)
{
// the exception passed in is going to be handed off to another thread,
// so it needs to be thread safe.
lock (exceptionDictionary)
{
exceptionDictionary[thread] = ex;
}
}
void ExceptionCheck()
{
lock (exceptionDictionary)
{
Exception ex;
if (exceptionDictionary.TryGetValue(Thread.CurrentThread, out ex))
throw ex;
}
}
void MethodOnThreadA()
{
for (;;)
{
// Do stuff
if (ErrorConditionMet)
ThrowOnThread(threadB, new MyException(...));
}
}
void MethodOnThreadB()
{
try
{
for (;;)
{
// Do stuff
ExceptionCheck();
}
}
catch (MyException ex)
{
// Do the right thing for this exception.
}
}
This is NOT a good idea
This article talks about ruby's timeout library. which throws exceptions across threads.
It explains how doing such a thing is fundamentally broken. It's not just broken in ruby, it's broken anywhere that throws exceptions across threads.
In a nutshell, what can (and does) happen is this:
ThreadA:
At some random time, throw an exception on thread B:
ThreadB:
try {
//do stuff
} finally {
CloseResourceOne();
// ThreadA's exception gets thrown NOW, in the middle
// of our finally block and resource two NEVER gets closed.
// Obviously this is BAD, and the only way to stop is to NOT throw
// exceptions across threads
CloseResourceTwo();
}
Your 'periodic checking' example is fine, as you're not actually throwing exceptions across threads.
You're just setting a flag which says "throw an exception the next time you look at this flag", which is fine as it doesn't suffer from the "can be thrown in the middle of your catch or finally block" problem.
However, if you're going to do that, you may as well just be setting an "exitnow" flag, and using that and save yourself the hassle of creating the exception object. A volatile bool will work just fine for that.
There are enough problems with exceptions that can be thrown on threads by other mechanisms, like aborting threads and the likes, that you should find another way of doing it.
An exception is a mechanism used to signal that a process has experienced something exceptional that it cannot deal with. You should try to avoid writing the code so that an exception is used to signal that something else has experienced something exceptional.
That other thread will most likely not know how to handle the exception in all cases where it could be thrown by your code.
In short, you should find some other mechanism for aborting your threads than using exceptions.
Use event objects or similar to tell a thread to abort its processing, that's the best way.
What Orion Edwards is saying is not entirely true: is not the "only" way.
// Obviously this is BAD, and the only way to stop is to NOT throw
// exceptions across threads
Using CER (Constrained Execution Regions) in C# allows you to release your resources as an atomic operation, protecting your code from inter-thread exceptions. This technique is used by several classes of the .NET Framework which work with Windows' native API, where an unreleased handle may cause a memory leak.
See http://msdn.microsoft.com/en-us/library/system.runtime.compilerservices.runtimehelpers.prepareconstrainedregions.aspx
The following example shows how to reliably set handles by using the PrepareConstrainedRegions method. To reliably set a handle to a specified pre-existing handle, you must ensure that the allocation of the native handle and the subsequent recording of that handle within a SafeHandle object is atomic. Any failure between these operations (such as a thread abort or out-of-memory exception) will result in the native handle being leaked. You can use the PrepareConstrainedRegions method to make sure that the handle is not leaked.
As simple as:
public MySafeHandle AllocateHandle()
{
// Allocate SafeHandle first to avoid failure later.
MySafeHandle sh = new MySafeHandle();
RuntimeHelpers.PrepareConstrainedRegions();
try { }
finally // this finally block is atomic an uninterruptible by inter-thread exceptions
{
MyStruct myStruct = new MyStruct();
NativeAllocateHandle(ref myStruct);
sh.SetHandle(myStruct.m_outputHandle);
}
return sh;
}
While researching another issue, I came across this article which reminded me of your question:
Plumbing the Depths of the ThreadAbortException using Rotor
It shows the gyrations that .NET goes through to implement Thread.Abort() -- presumably any other cross-thread exception would have to be similar. (Yeech!)
I'm interested to know why you would want to do this. There's not an easy way to do it, because it's not a good practice. You should probably go back to your design and figure out a cleaner way to accomplish the end goal.
I don't think that's a good idea..
Take another crack at this problem - Try using some other mechanism like shared data to signal between threads.
Like the others, I'm not sure that's such a good idea, but if you really want to do it, then you can create a subclass of SynchronizationContext that allows posting and sending delegates to the target thread (if it's a WinForms thread the work is done for you as such a subclass already exists). The target thread will have to implement some sort of a message pump equivalent though, to receive the delegates.
#Orion Edwards
I take your point about an exception being thrown in the finally block.
However, I think there is a way - using yet another thread - of using this exception-as-interrupt idea.
Thread A:
At some random time, throw an exception on thread C:
Thread B:
try {
Signal thread C that exceptions may be thrown
//do stuff, without needing to check exit conditions
Signal thread C that exceptions may no longer be thrown
}
catch {
// exception/interrupt occurred handle...
}
finally {
// ...and clean up
CloseResourceOne();
CloseResourceTwo();
}
Thread C:
while(thread-B-wants-exceptions) {
try {
Thread.Sleep(1)
}
catch {
// exception was thrown...
if Thread B still wants to handle exceptions
throw-in-B
}
}
Or is that just silly?

Categories