Sending an exception from thread to main thread? - c#

I want to pass an exception from current thread (that thread isn't main thread)to main thread.
Why? Because I check my hard lock in another thread (that thread use timer for checking), and when HardLock is not accessible or invalid, I create an exception which is defined by myself and then throw that exception.
So that exception doesn't work well. ;(

Your best bet is to replace the Thread with a Task (new in .NET 4.0). The Task class handles proper marshaling of the exception to whatever thread checks the result of the task.
If using .NET 4.0 is not possible, then CoreEx.dll from the Rx extensions includes an Exception.PrepareForRethrow extension method that preserves the call stack for exceptions. You can use this in conjunction with MaLio's suggestion of SynchronizationContext to marshal an exception to another thread.

You can use the exception as an parameter in event.
And handle it after sending the exception to other thread.
Code example.
public delegate void SendToMainDel(string threadName,Exception ex);
public event SendToMainDel SendToMainEv;
public void MySecondThread()
{
try
{
....
}catch(Exception ex)
{
if(SendToMainEv!=null)
SendToMainEv("MySecondThread",ex);
}
}
...
SendToMainEv += ReceiveOtherThreadExceptions;
...
public void ReceiveOtherThreadExceptions(string threadName,Exception ex)
{
if(InvokeRequired)
{
BeginInvoke(new SendToMainDel(ReceiveOtherThreadExceptions), threadName, ex);
return;
}
//there you can handle the exception
//throw ex;
}

Knowing nothing else, it seems like your locking is broken, if you need a thread to ensure that your locks aren't held too long or are invalid.
If you really need to throw exceptions to your main thread, set up a communication queue from all your 'worker threads' to your 'master thread', and wrap your entire worker threads in an exception handler that does nothing more than append exceptions to the queue and then kills that thread. Your master thread can poll the queue to discover exceptions and restart threads that have died after correcting the error condition.

Pass along a reference to the execution context of the main form to the thread (via the delegate or field). Then invoke a method (either send or post) via that synchronization context from your thread that throws the exception. The execution context will ensure it is processed by the ui thread.

You might find it easier to keep the exception handling within the thread and pass back the exception message and stack trace by returning MyException.ToString() in a callback. When I get exceptions from another thread, everything I'm looking for is in that string.

Just my 2 cents.
I think you can use Invoke, BeginInvoke on the main form if you are running Windows Forms to send an exception there from try/catch block. Or you can create an event handler/delegate in a main thread and send exceptions through that to the main thread so the method in a main thread can process it. To be honest haven't tried those solutions but those are my first ideas.
PS. Maybe creating a WorkerQueue on the main thread is also an option. It will run as a backgroundWorker and when it gets new exception sent in it processes it accordingly... I can give you small examples on that if you're interested.
Edit:
public class JobQueue
{
private Queue<Exception> pendingJobs = new Queue<Exception>();
private Exception defaultJob = null;
bool run = true;
public void AddJob(Exception job)
{
pendingJobs.Enqueue(job);
}
public JobQueue()
{
defaultJob=null;
}
public void StopJobQueue()
{
run = false;
}
public void Run()
{
while (run)
{
Exception job = (pendingJobs.Count > 0) ? pendingJobs.Dequeue() : defaultJob;
if (job!= null)
{
////what to do with current Exception
}
Thread.Sleep(20); //I know this is bad...
}
pendingJobs.Clear();
}
}
}
To use it:
In your main thread class:
private JobQueue m_jobQueue;
In Initialize() or wherever your main thread starts:
Backgroundworker bw = new Backgroundworker();
bw.DoWork+= jobQueue.Run;
bw.StartAsync();
//m_jobQueue = new JobQueue();
// new Thread(new ThreadStart(jobQueue.Run)).Start();
And to send an exception use:
m_jobQueue.AddJob(StackOverflowException);
Stop by:
m_jobQueue.StopJobQueue();

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

c# catch an exception from delegate.begininvoke without calling delegate.endinvoke

I have a program that monitor a DB (or a number of DBs).
for this, I built a class that holds all the information about how to monitor the DB.
the class contains a delegate that points to a function that monitor the DB and changes the state field accordingly.
the main thread create a new instance of the class and calling the class.delegate.begininvoke().
the main thread checks the state of each created class in a loop and inform the user if any changes occur.
a simple example of the code:
Class Monitor
{
private Object lockObj;
private delegate void MonitorHandlerDelegate();
private MonitorHandlerDelegate mainHandler;
private int State;
private int DBid;
public Monitor(int DBid)
{
this.DBid = DBid;
mainHandler += MonitorHandler;
lockObj = new Object();
}
private void MonitorHandler()
{
do
{
state = CheckDB(DBid); // 0 is ok, 1 is fail, 2 is InWork, 3 is stop monitoring
} while (state != 3);
}
public int state
{
get { lock(lockObj) { return State;} }
set { lock(lockObj) {State = value;} }
}
public void Start()
{
this.state = 0;
this.mainHandler.BeginInvoke(null, null);
}
}
public Main()
{
Monitor firstMonitor = new Monitor(20);
firstMonitor.Start();
do
{
if(firstMonitor.state == 1) WriteLine("DB 20 stop working");
} while(true);
}
The problem I encountered is with exception handaling, if the MonitorHandler function throw an exception, i dont have a way to know it.
I dont call the EndInvoke so the exception is not re-throwing to the Main Thread.
My goal is to check the DB status by simply chack the state field of the monitor instance.
If an exception in throwen i need to somehow "transfer" this exception to the Main Thread but i dont want to start checking the state and the Monitor delegate status as well.
I whold love to find a way to the Monitor Thread itself (the one that activated by the .BeginInvoke), to throw the exception in the Main Thread.
Thank you.
I whold love to find a way to the Monitor Thread itself (the one that activated by the .BeginInvoke), to throw the exception in the Main Thread.
Other than something like ThreadAbortException, there is no mechanism to inject an exception into another arbitrary thread.
If you are going to use the delegate's BeginInvoke() method, and you want to catch the exception in a thread different from where the delegate itself is being invoked, then you will need to call EndInvoke() in that thread.
Your other option would be to deal with the exception explicitly and manually. I.e. catch the exception with try/catch in the worker thread, and then use an explicitly defined mechanism of your own choosing (e.g. a ConcurrentQueue<T>) to pass the caught exception to code running in the main thread.
All that said, using a delegate's BeginInvoke() method was never really that ideal a way to execute code asynchronously like that, and today it is even worse of an idea. It's not clear from your question what the nature of the "main thread" is, never mind whether that thread has a synchronization context. But assuming it does (e.g. it's a GUI thread, or an ASP.NET context, etc.) then your desired behavior is easily implemented using Task.Run() to start the asynchronous operation, and then using await in the main thread to capture the completion of that operation, along with any exception that is thrown.
For that matter, even if your main thread does not currently have a synchronization context, it might be the right approach is to give it one. Either by leveraging one of the existing mechanisms, or writing your own. This would be a good idea if, for example, you expect to run into this sort of "propagate the exception from the worker to the main thread" scenario in the code frequently. This would allow you to use the built-in language support for dealing with that (i.e. async/await), rather than having to kludge something for each instance. Implementing the synchronization context isn't trivial, but it's work you can do once, and then reuse over and over.

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.

Where should my Try Catch block be when running a thread?

Take this thread:
Thread thread = new Thread(delegate()
{
//Code
});
thread.Start();
Should it be around the thread.Start(); or inside:
Thread thread = new Thread(delegate()
{
try
{
//Code
}
catch (Exception)
{
//Code
}
});
it is completely different to put then inside or outside.
If you put them around the thread.Start() call, you can detect (according to this page: http://msdn.microsoft.com/en-us/library/system.threading.thread.start(v=vs.71).aspx)
ThreadStateException The thread has already been started.
SecurityException The caller does not have the appropriate SecurityPermission.
OutOfMemoryException There is not enough memory available to start this thread.
NullReferenceException This method was invoked on a thread reference that is a null reference (Nothing in Visual Basic).
If you put it inside, you will detect exception inside the code you will run in your thread. So any kind of exception you want.
The exceptions pertaining the logic you have in the delegate should be handled inside the delegate.
thread.Start() itself can only throw ThreadStateException or OutOfMemoryException.
Preventing silent thred termination
It explains to place the try catch inside of the delegate. It also talks about doing your finnally clean up if needed.
If, as you mention above, the error is in the delegate code, then put the try-catch in there and log the exception. Alternatively, if you want that exception to be passed back to the original thread use an asynchronous delegate (calling EndInvoke will re-raise the exception to the calling thread or use Background worker and subscribe to RunWorkerCompleted event (this has error property in event args).

Categories

Resources