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.
Related
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!
}
}
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.
I am trying to understand data parallelism and processes in C#(Reference) and am getting a bit confused by the behavior. I may be missing some really basic concept , but it would be great if anyone could explain this
So I have the following code :-
private static void Process()
{
Process _process = new Process();
_process.StartInfo.FileName = "C:\\Windows\\notepad.exe";
_process.StartInfo.UseShellExecute = false;
_process.StartInfo.RedirectStandardOutput = true;
// Start the process
_process.Start();
_process.BeginOutputReadLine();
Task task = Task.Factory.StartNew(() => MonitorProcess());
Console.WriteLine("Main ");
}
private static void MonitorProcess()
{
Console.WriteLine("Inside Monitor");
string x = null;
x = x.Trim();
}
Now my expectation is that "Main" should never be printed to the console since there is a null reference exception in the MonitorProcess method . I don't want to use task.Wait() to catch and throw the exception since that will wait for the task to complete.
So why does this happen and how can i get around this so that code execution is stopped at the exception in the MonitorProcess method ?
A task is run in a seperate thread (one from the thread pool). The exception isn't thrown in the main thread, so why should the main thread stop?
Since the two threads execute in parallel, it might even be possible for your Process method to print (and return) before the exception is even thrown in the MonitorProcess method.
If you want your main thread to stop, you have to propagate the exception to it. You can find a few examples how to do this here: A Task's exception(s) were not observed either by Waiting on the Task or accessing its Exception property. As a result, the unobserved exception was
But doing this without waiting in the main thread will still not stop the main thread from printing because, as I already said, that code might have already been executed.
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.
I dont know why but i can no longer interrupt my own thread.
thread = new Thread(new ParameterizedThreadStart(this.doWork));
thread.Start(param);
...
thread.Interrupt();
//in doWork()
try {
...
}
catch (System.Threading.ThreadInterruptedException)
{
//it never hits here. it use to
}
I search and i dont have any catch in my code and this is the only catch (System.Threading.ThreadInterruptedException). So what is going on? Using the debugger i can see my code run through the thread.Interrupt();. If i do thread.abort() i will catch a System.Threading.ThreadAbortException exception. Why is it catching that and not ThreadInterruptedException?
From BOL:
Interrupts a thread that is in the
WaitSleepJoin thread state.
If this thread is not currently
blocked in a wait, sleep, or join
state, it will be interrupted when it
next begins to block.
ThreadInterruptedException is thrown
in the interrupted thread, but not
until the thread blocks. If the thread
never blocks, the exception is never
thrown, and thus the thread might
complete without ever being
interrupted
BTW, you might be better off using the BackgroundWorker Class which supports cancelling.
From acidzombie24's comment to another answer:
So .abort is a better option? What i want to do is kill the thread but have it exist and call a few functions instead of outright death
Something like an event would be better.
Assuming you want to be able to signal each thread separately, before each worker thread is started create an AutoResetEvent and pass it to the thread.
When you want to interrupt the thread call Set on the event. In the worker thread check the state of the event regularly:
if (theEvent.WaitOne(TimeSpan.Zero)) {
// Handle the interruption.
}
(Regularly: needs to be defined by the requirements: overhead of checking vs. latency of interruption.)
To have a master interrupt, to signal all workers, use a ManualResetEvent which will stay signalled, and keep interrupting threads when they check, until explicitly Reset.