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

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).

Related

Exception caught in System.Threading.Timers TimerCallback event handler and then re-thrown not sent back to main thread

I need for exceptions thrown within a timed event to be bubbled up and handled outside of the event handler context. I had read that System.Threading.Timers would be able to do that, provided that, as outlined in the answer to this question, the exception is caught in the callback method and a mechanism is used to re-throw it. Using this example as a guide, I created an event handler which throws and a method which should catch and re-throw the exception using an IProgress object:
void ThrowerThreaded() {
var progress = new Progress<Exception>((ex) => {
throw ex;
});
Timer timer = new Timer(x => onTimerElapsedThrow2(progress), null, 10, -1);
Thread.Sleep(1000);
}
void onTimerElapsedThrow2(IProgress<Exception> progress) {
try {
throw new Exception();
} catch (Exception ex) {
progress.Report(ex);
}
}
I then wrote a unit test to see if the exception would bubble up:
[TestMethod]
public void TestThreadedTimerThrows() {
Assert.ThrowsException<Exception>(ThrowerThreaded);
}
The test case fails indicating no exception was thrown. If I debug the test case, I can clearly see that the exception is caught and re-thrown in ThrowerThreaded() however the method still continues and exists normally. Why is the exception still being suppressed?
I'm guessing ThrowerThreaded is running on a background thread. That means it does not have a synchronizationContext, since these are intended to synchronize UI applications. This means the callback is called on the threadpool:
Any handler provided to the constructor or event handlers registered with the ProgressChanged event are invoked through a SynchronizationContext instance captured when the instance is constructed. If there is no current SynchronizationContext at the time of construction, the callbacks will be invoked on the ThreadPool.
Rethrowing the exception on a threadpool thread will probably kill that thread, and I'm somewhat surprised it did not kill the application, but it's possible that such behavior is overridden by the testing framework you are using.
To solve this you really need to handle the exception in the callback instead of re-throwing it. If you are not handling the exception, who should? there is a unhandledExceptionEvent, but that is intended for logging before you close your app.
You could handle the exception taking a callback in ThrowerThreaded that you delegate the exception handling to. Another alternative would be to create a TaskCompletionSource that allow you to return a task, and set the task to 'failed' by calling SetException on the source.
It is also poor practice to re-throw the same exception object, since you will lose the call stack, you should instead wrap the exception in a new exception that is thrown.

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.

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.

Sending an exception from thread to main thread?

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();

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