Expected ThreadAbort for Background Thread - c#

I have the following.
public static Thread testThread = new Thread(ThreadStart) {Name = "TestThread", IsBackground = true};
private void Form_Load()
{
testThread.Start()
}
private static void ThreadStart()
{
int count = 0;
try
{
while (true)
{
count++;
}
}
catch (Exception ex)
{
StreamWriter stream = new StreamWriter(File.OpenWrite("Exception.txt"));
stream.WriteLine(count + "\n" + ex);
stream.Flush();
stream.Close();
}
}
When I call Thread.Abort() I catch the exception and write out to the file.
However, if I instead close the application nothing is written.
I also have
AppDomain.CurrentDomain.UnhandledException +=
new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
Application.SetUnhandledExceptionMode(UnhandledExceptionMode.ThrowException);
Application.ThreadException +=
new System.Threading.ThreadExceptionEventHandler(Application_ThreadException);
But it doesn't appear an exception is ever thrown.
I suppose adding a question is prudent.
What happens to a running background thread when the parent processes exits?
My understanding was a ThreadAbortException is thrown to exit the thread.
If this is the case, how can the ThreadAbortException be caught in order to clean up resources that may be present in the thread?

First of all, the application probably isn't exiting, because you are not making these into background threads. My guess is that Task Manager will show copies of your EXE running unexpectedly. You need to set Thread.IsBackground to true on the thread object before calling Start.
Secondly, the behavior that you expect is explicitly debunked by the documentation:
Note
When the common language runtime (CLR) stops background threads,
after all foreground threads in a managed executable have ended, it
does not use System.Threading.Thread.Abort. Therefore, you cannot use
ThreadAbortException to detect when background threads are being
terminated by the CLR.
EDIT:
When a process is exiting, there is no need to clean up resources held by the worker threads because, you know, the process is exiting. The contract with regard to background threads is that they can be killed at any time when the process exits. Therefore, if your background threads are doing something that requires transactional correctness, they probably should not be background threads. Make 'em foreground threads and have them periodically check or wait on a reset event to see whether they should exit and allow the process to end.

When the CLR shuts down a process it does not call Thread.Abort or anything similar. Your thread methods will not exit like your main method.
The first thing it does when you leave the main method or call Environment.Exit is to finalize all objects with a timeout (it was 2s in .NET 2.0) then it will continue to terminate the application regardless of the current pending finalizers.
Next the Critical Finalizers are called.
Then all threads are suspended so they do not cause harm while the CLR is shutting down.
You application has exited.

If the IsBackground property of your thread is false, then your thread would remain alive, even when the main window of your application is closed.
The best way to control the lifetime of background threads is to create sentinels, typically implemented as volatile bool fields, which the code within the thread checks at regular intervals (for example, on every iteration). The thread should stop executing when the sentinel indicates that the application is terminating.
The following code shows the use of a sentinel to terminate the thread after 200 milliseconds:
public static Thread testThread = new Thread(ThreadStart)
{
Name = "TestThread",
IsBackground = false // Allow thread to terminate naturally
};
private static volatile bool isTerminating = false; // Sentinel
private void Form_Load()
{
testThread.Start();
Thread.Sleep(200); // Sleep 200 milliseconds
isTerminating = true; // Set sentinel to terminate thread
}
private static void ThreadStart()
{
int count = 0;
while (!isTerminating) // Keep looping until sentinel is set
count++;
using (StreamWriter stream = new StreamWriter(File.OpenWrite("Result.txt")))
{
stream.WriteLine(count);
stream.Flush();
}
}
Edit: To answer your last question, “How can the ThreadAbortException be caught in order to clean up resources that may be present in the thread?” You can use an ordinary catch block. ThreadAbortException may be caught like any other exception, but it will automatically be raised again at the end of the catch block. However, as Chris mentioned, if the process is exiting, the ThreadAbortException is not raised at all.

Related

Can this cause deadlock? BeginInvoke() & thread.Join()

I have this code that many threads can call to update the GUI:
MethodInvoker del = () => { lblInfo.Text = tmp; };
lblInfo.BeginInvoke(del);
(lblInfo is created by the GUI thread)
I also have this method called at button click executed by the GUI thread:
public void Stop()
{
isStopping = true;
crawler.Join();
foreach (Thread t in txtWorkers)
{
t.Join();
}
indexer.Join();
lblStatus.Text = "Stopped";
lblInfo.Text = "";
}
1 time over 100 run the program deadlock at Stop button click. I was not debugging when i saw the deadlock so i can't be sure about the state of the various threads but i'm almost sure that all the threads i'm joining will eventually reach the point where they check for
isStopping value and terminate. This leads me to think that there may be a problem with the BeginInvoke but can't really find it. It should be async so threads calling it (crawler & indexer) should not block. What happens if the GUI thread is executing Stop() and also must execute a call from BeginInvoke? Could this be the problem? Is there something i can't see about the thread i'm joining?
EDIT:
What the code looks like after the suggested changes:
public void Stop()
{
/*
...disable GUI
*/
isStopping = true; // Declared as volatile
lblStatus.Text = "Stopping...";
// Creating a thread that will wait for other threads to terminate
Task.Factory.StartNew(() =>
{
crawler.Join();
foreach (Thread t in txtWorkers)
{
t.Join();
}
indexer.Join();
// Adjust UI now that all threads are terminated
MethodInvoker del = () =>
{
/*
...enable GUI
*/
lblStatus.Text = "Not Running";
isStopping = false;
};
lblStatus.BeginInvoke(del);
});
}
It seems to be working, i hope that deadlock is gone...
I don't think it should be a problem, because you're using BeginInvoke rather than Invoke - the background threads will just proceed past that line without waiting for the GUI to catch up. If you're using Control.Invoke anywhere, that could cause a deadlock.
More importantly, using Join in your GUI thread is fundamentally a bad idea - the UI will be frozen until everything's finished. It would be better to disable any controls which could start anything new, set your isStopping flag, and then create a new thread to wait for all the threads to stop - and when all the threads have finished, then update the UI with BeginInvoke again. (If you're using .NET 4.5 you could also use an asynchronous method for this, creating and awaiting a task to wait for all the threads.)
Finally, if isStopping is just a bool field, there's no guarantee that your background threads will "see" the change from the UI thread. It's possible that making the field volatile would fix this, but the precise meaning of volatile scares me. An alternative would be to use the Interlocked class, or make it a property which obtains a lock for both reading and writing - that ensures appropriate memory barriers are in place.

stopping my thread

I have a thread that I am trying to discontinue. What I have done is the following.
randomImages = new Thread(new ThreadStart(this.chooseRandomImage));
randomImages.Start();
This is the method called by the thread
bool threadAlive = true;
public void chooseRandomImage()
{
while(threadAlive)
{
try
{
//do stuff
}
catch (Exception exe)
{
MessageBox.Show(exe.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
Now, upon clicking a stop thread button I simply set threadAlive to false.
Problem is the thread doesnt stop immediately, as if it has gathered a form of momentum.
How can a stop a thread instantly, and possibly restart it again?
private void butStopThread_Click(object sender, EventArgs e)
{
threadAlive = false;
if(threadAlive == false)
{
//do stuff
}
}
I am sorry, that IS the best way to do it. Using .NET 4.0 upward you should use tasks, not threads, and then there is this thing called CancellationToken that pretty much does the same as your variable.
Then, after cancelling, you wait until the processing is finishing. If that needs to happen fast, then - well - make the check for the cancellation more granular, i.e. check more often.
Aborting threads has possibly significant side effects as explained at http://www.interact-sw.co.uk/iangblog/2004/11/12/cancellation - this is why the method generally should not be used.
And no, stopped threads etc. can not be restarted magically - this you have to put into your logic (restart points, save points ,long running transaction in steps, remembering where it finished).
As a sidenote - if you insist on not using tasks and have access to the latest versin of .NET, Volatile is not needed if you use the Interlocked access class methods, which ago down to some assembler instructions that are thread safe per definition.
It is possible to terminate a thread from another thread with a call
to Abort, but this forcefully terminates the affected thread without
concern for whether it has completed its task and provides no
opportunity for the cleanup of resources. The technique shown in this
example is preferred.
You need to use Abort method BUT IS NOT RECOMMENDED
From the information provided by you, it seems the threadAlive variable is being accessed by both the worker thread and the UI thread. Try declaring threadAlive using volatile keyword which is ensure cross-thread access happens without synchronization issues.
volatile bool threadAlive;
To restart the thread, you first need to ensure that it performs all necessary cleanup. Use the Join method call on your thread object in the main/UI thread to make sure your thread terminates safely. To restart, simply invoke the Start method on the thread.
randomImages.Join();

Shutdown a thread waiting on a timer in a Windows Service

I have a .Net 4.0 C# Windows Service which spawns a number of thread which run continuously. Each thread runs at different intervals based on a timer.
I want to shut these threads down gracefully when the service is shutdown.
Since some of these threads may be waiting for hours to do it's processing, I need to wake them up and tell them to exit.
I could create a loop in these threads to periodically check some global variable at some interval less that their processing interval, but I would prefer a signaling mechanism which would cause them the timer to pop prematurely.
How can I wake these threads waiting on a timer without using Thread.Abort or Thread.Interrupt?
I'm going to assume that you have a good reason for using independently managed threads to do the work (as opposed to just doing it in the timer's event). If so, you want to use WaitHandle.WaitAny() and examine the return value to determine which WaitHandle caused the thread to proceed:
public class ExampleService
{
private static readonly AutoResetEvent TimerLatch = new AutoResetEvent(false);
private static readonly AutoResetEvent ShutdownLatch = new AutoResetEvent(false);
private static readonly Timer MyTimer = new Timer(TimerTick);
public void Start()
{
var t = new Thread(DoLoop);
t.Start();
MyTimer.Change(0, 500);
}
public void Stop()
{
ShutdownLatch.Set();
}
private static void TimerTick(object state)
{
TimerLatch.Set();
}
private static void DoLoop()
{
if (WaitHandle.WaitAny(new[] { TimerLatch, ShutdownLatch }) == 0)
{
// The timer ticked, do something timer related
}
else
{
// We are shutting down, do whatever cleanup you need
}
}
}
You can use WaitHandle.Waitone with a timeout and use events
if (shutDownEvent.WaitOne(_timeout, false ))
{
//Shutdown
}
else
{
//timeout so Dowork
}
Depending on your scenario it might be an option to make the threads you spawn background threads so you don't have to worry about explicitly shutting them down.
Thread thread = new Thread(DoSomething)
{
IsBackground = true
};
Setting IsBackground to true makes the spawned thread a background thread which won't stop your service from terminating.
From MSDN:
A thread is either a background thread or a foreground thread.
Background threads are identical to foreground threads, except that
background threads do not prevent a process from terminating. Once all
foreground threads belonging to a process have terminated, the common
language runtime ends the process. Any remaining background threads
are stopped and do not complete.
This of course is only an option if whatever operation you are performing may be interrupted and don't have to gracefully shut down (e.g. do some critical cleanup work). Otherwise as both other answers are suggesting you should use a WaitHandle, and signal from the main thread.

Shutting down a multithreaded application

I'm trying to write a ThreadManager for my C# application. I create several threads:
One thread for my text writer.
One thread that monitors some statistics.
Multiple threads to perform a large sequence of calculations (up to 4 threads per core and I run my app on a 2x quad core server).
My application normally runs for up to 24 hours at a time, so all the threads get created in the beginning and they persist through the entire time the app runs.
I want to have a single place where I "register" all of my treads and when the application is shutting down I simply invoke a method and it goes through all of the registered threads and shuts them down.
For that purpose I have devised the following class:
public class ThreadManager
{
private static Object _sync = new Object();
private static ThreadManager _instance = null;
private static List<Thread> _threads;
private ThreadManager()
{
_threads = new List<Thread>();
}
public static ThreadManager Instance
{
get
{
lock (_sync)
{
if (_instance == null)
{
_instance = new ThreadManager();
}
}
return _instance;
}
}
public void AddThread(Thread t)
{
lock (_sync)
{
_threads.Add(t);
}
}
public void Shutdown()
{
lock (_sync)
{
foreach (Thread t in _threads)
{
t.Abort(); // does this also abort threads that are currently blocking?
}
}
}
}
I want to ensure that all of my threads are killed so the application can close properly and shutting down in the middle of some computation is just fine too. Should I be aware of anything here? Is this approach good given my situation?
If you set the threads to background threads, they will be killed when the application is shut down.
myThread.IsBackground = true;
obviously if you need the threads to finish before shutdown, this is not the solution you want.
Aborting threads is what you do when all else fails. It is a dangerous thing to do which you should only do as a last resort. The correct way to do this is to make your threading logic so that every worker thread responds quickly and correctly when the main thread gives it the command to shut itself down.
Coincidentally, this is the subject of my blog this week.
http://blogs.msdn.com/ericlippert/archive/2010/02/22/should-i-specify-a-timeout.aspx
What if AddThread is called while your Shutdown is running?
When shutdown finishes, the thread waiting in AddThread will add a new thread to the collection. This could lead to hangs in your app.
Add a bool flag that you ever only set in Shutdown to protect against this.
bool shouldGoAway = false;
public void AddThread(Thread t)
{
lock (_sync)
{
if( ! shouldGoAway )
_threads.Add(t);
}
}
public void Shutdown()
{
lock (_sync)
{
shouldGoAway = true;
foreach (Thread t in _threads)
{
t.Abort(); // does this also abort threads that are currently blocking?
}
}
Also you should not use static members - there is no reason for that as you have your Singleton instance.
.Abort() does not abort threads that are blocking in unmanaged space. So if you do that you need to use some other mechanism.
The only specific issue I know about is this one: http://www.bluebytesoftware.com/blog/2007/01/30/MonitorEnterThreadAbortsAndOrphanedLocks.aspx
But I'd avoid having to resort to a design like this. You could force each of your threads to check some flag regularly that it's time to shut down, and when shutting down, set that flag and wait for all threads to finish (with Join()). It feels a bit more like controlled shutdown that way.
If you don't care about the worker thread state then you can loop through _thread and abort:
void DieDieDie()
{
foreach (Thread thread in _thread)
{
thread.Abort();
thread.Join(); // if you need to wait for the thread to die
}
}
In your case you can probably just abort them all and shutdown as they're just doing calculations. But if you need to wait for a database write operation or need to close an unmanaged resource then you either need to catch the ThreadAbortException or signal the threads to kill themselves gracefully.
You want deferred thread cancellation, which basically means that the threads terminate themselves as opposed to a thread manager cancelling threads asynchronously, which is much more ill-defined and dangerous.
I you wanted to handle thread cancellation more elegantly than immediate termination, you can use signal handlers that are triggered by events outside the thread - by your thread manager perhaps.

How to kill a thread instantly in C#?

I am using the thread.Abort method to kill the thread, but it not working. Is there any other way of terminating the thread?
private void button1_Click(object sender, EventArgs e)
{
if (Receiver.IsAlive == true)
{
MessageBox.Show("Alive");
Receiver.Abort();
}
else
{
MessageBox.Show("Dead");
Receiver.Start();
}
}
I am using this but every time I get the Alive status, Receiver is my global thread.
The reason it's hard to just kill a thread is because the language designers want to avoid the following problem: your thread takes a lock, and then you kill it before it can release it. Now anyone who needs that lock will get stuck.
What you have to do is use some global variable to tell the thread to stop. You have to manually, in your thread code, check that global variable and return if you see it indicates you should stop.
You can kill instantly doing it in that way:
private Thread _myThread = new Thread(SomeThreadMethod);
private void SomeThreadMethod()
{
// do whatever you want
}
[SecurityPermissionAttribute(SecurityAction.Demand, ControlThread = true)]
private void KillTheThread()
{
_myThread.Abort();
}
I always use it and works for me:)
You should first have some agreed method of ending the thread. For example a running_ valiable that the thread can check and comply with.
Your main thread code should be wrapped in an exception block that catches both ThreadInterruptException and ThreadAbortException that will cleanly tidy up the thread on exit.
In the case of ThreadInterruptException you can check the running_ variable to see if you should continue. In the case of the ThreadAbortException you should tidy up immediately and exit the thread procedure.
The code that tries to stop the thread should do the following:
running_ = false;
threadInstance_.Interrupt();
if(!threadInstance_.Join(2000)) { // or an agreed resonable time
threadInstance_.Abort();
}
thread will be killed when it finish it's work, so if you are using loops or something else you should pass variable to the thread to stop the loop after that the thread will be finished.
C# Thread.Abort is NOT guaranteed to abort the thread instantaneously. It will probably work when a thread calls Abort on itself but not when a thread calls on another.
Please refer to the documentation: http://msdn.microsoft.com/en-us/library/ty8d3wta.aspx
I have faced this problem writing tools that interact with hardware - you want immediate stop but it is not guaranteed. I typically use some flags or other such logic to prevent execution of parts of code running on a thread (and which I do not want to be executed on abort - tricky).

Categories

Resources