I want to kill a thread when something very bad happen. What's your suggestion to do thread suicide?
You should never actually "kill" a thread. From your main program, you can abort it using the Thread.Abort method, but this is not recommended, and it is completely unnecessary.
Your thread should be nothing more than a method executing a long loop. If something "really bad" happens, simply return from this method and thread will end.
This would be enough for such a loop:
private void MyThreadLoop()
{
try
{
while (someCondition)
{
// do a lengthy operation
}
}
catch (Exception ex)
{
Log.Error("Something bad happened: ", ex);
}
}
public void Start()
{
Thread t = new Thread(MyThreadLoop);
t.Start()
}
On the other hand, if you need your main program to kill the thread (but this is not a "suicide" as you named it), then you should signal the thread that you want it to end, and not abort it without knowing what is going on in the background.
There's no need to completely kill a thread, all you need to do is have it stop working on the current task.
Inside of thread, its enough to return from its function. Outside of thread, there is method Thread.Abort().
You could try something like this. The thread runs until it receives a signal from "outside" and then exists.
private static void Main(string[] args)
{
var shouldExit = new AutoResetEvent(false);
ThreadPool.QueueUserWorkItem(
delegate
{
while (true)
{
Console.WriteLine("Running...");
if (shouldExit.WaitOne(0)) break;
}
Console.WriteLine("Done.");
});
// wait a bit
Thread.Sleep(1000);
shouldExit.Set();
Console.ReadLine();
}
Related
I am trying to end my Thread, within the thread, and when aborted, i want to detect that the thread has been aborted (or just, stopped really)
This is what i am doing to do that, but isnt working as it never gets to this part
if (!thread.IsAlive){
CommandPrompt.SayMessage("Oops! MBP thread died.");
}
This is how i'm going about it, thank you for the help. sorry if my question is confusing please ask questions so i can help you help me :) thanks!
public static Thread thread;
public static void 1()
{
thread = new Thread(thread1);
thread.Start();
if (!thread.IsAlive)
{
CommandPrompt.SayMessage("Oops! MBP thread died.");
}
}
public static void thread1()
{
{
int test = 0;
while (thread.IsAlive){
Console.WriteLine("running.."); // this text will be displayed when the thread is active, and will stop when stopped.
Thread.Sleep(2500);
test += 1;
if (test > 4) // after 4 loops, i want the thread to end itself
thread.Abort();
}
if (!thread.IsAlive){ // once the thread is ended i want it to tell us that, but it never gets to this part.
CommandPrompt.SayMessage("Oops! MBP thread died.");
}
}
}
If you want to check if a thread is still alive, you cannot do that from the code running in that particular thread. Because, if you can execute the code to check if the thread is still alive, it is -- obviously -- still alive. And if the thread is not alive anymore it will -- obviously -- not be able to execute any more code ...
So the only way is to do this from somewhere outside the thread (ie some other thread, maybe even the main thread).
Just schematic code, which is rather clumsy, but will give you a first idea of how you can address this issue. But if there is a third party messing around with your threads, that won't help anything, because what prevents them from killing off your whole application?
public class ThreadTest {
static bool ranToEnd = false;
public static void Main(){
var thread = new Thread(aThread);
var lc = 1;
thread.Start();
while (true){
if (!aThread.IsAlive) {
if (ranToEnd)
Console.WriteLine("aThread terminated normally");
else
Console.WriteLine("aThread ended prematurely");
break;
} else if (++lc == 10) {
aThread.Abort(); //Simulating the abortion of the thread
}
Thread.Sleep(1000);
}
}
public static void aThread() {
//do some work in this thread
// if the thread ran to an end normally, this will be set to true
// if the thread ended prematurely, this will stay false ...
ranToEnd = true;
}
}
Can anyone give me a headstart on the topic of threading? I think I know how to do a few things but I need to know how to do the following:
Setup a main thread that will stay active until I signal it to stop(in case you wonder, it will terminate when data is received). Then i want a second thread to start which will capture data from a textbox and should quit when I signal it to that of which occurs when the user presses the enter key.
Cheers!
This is how I do it...
public class ThreadA {
public ThreadA(object[] args) {
...
}
public void Run() {
while (true) {
Thread.sleep(1000); // wait 1 second for something to happen.
doStuff();
if(conditionToExitReceived) // what im waiting for...
break;
}
//perform cleanup if there is any...
}
}
Then to run this in its own thread... ( I do it this way because I also want to send args to the thread)
private void FireThread(){
Thread thread = new Thread(new ThreadStart(this.startThread));
thread.start();
}
private void (startThread){
new ThreadA(args).Run();
}
The thread is created by calling "FireThread()"
The newly created thread will run until its condition to stop is met, then it dies...
You can signal the "main" with delegates, to tell it when the thread has died.. so you can then start the second one...
Best to read through : This MSDN Article
Thread th = new Thread(function1);
th.Start();
th.Abort();
void function1(){
//code here
}
Use a static AutoResetEvent in your spawned threads to call back to the main thread using the Set() method. This guy has a fairly good demo in SO on how to use it.
AutoResetEvent clarification
I am running a while loop which keeps track of some events forever, In case if i get any exception i am changing its reference to null hoping that the current thread will be aborted and the new reference of that thread will be created. Is it correct or any better way to abort the current thread and start a newer one.
I am trying to do this:
Thread th;
Main()
{
th = new thread(myfunction);
th.Start();
}
void myfunction()
{
while(true)
{
try
{
// something interesting here.
}
catch(exception)
{
th = null;
}
}
}
Only thing that will happen is that Thread will remain inaccessible from the Enclosing class.
If there are no further processing, doing so will make the thread out of reach from GC appllication roots. This makes object available for garbage collection in next GC trigger.
You need to do:
return;
instead of:
th = null;
Because the thread will keep on running. The thread object will not get collected, since it will stay referenced as long as the code is running.
Clean up anything you need to for that thread, then break out of the while loop like this:
void runningOnThread()
{
while (true)
{
try
{
//...
}
catch (Exception e)
{
break;
}
}
//thread cleanup code goes here, if you have any.
}
It would be a good idea to log the exception when you catch it. That way you know when you've hit an exception.
First, if you run into an exception, before worrying about starting a new thread, be sure that you actually handle the exception and ensure that the restarted thread will be able to run successfully. Otherwise, you're just going to get a constant stream of crashing threads, and a choppy program while it handles the exception parade. Just some food for thought.
Now, answering the question, best case nulling the reference to the thread will just leave you in an infinite loop, worst case you try to use 'th' later and you get an exception because it's null. Nulling the reference to the thread won't somehow make it aware that it needs to restart itself any more than nulling a reference to parameter you gave it as a function argument will. If you absolutely need some kind of ability to abort/restart the thread, look into doing one of:
raising an event when the thread crashes and break out of the while loop, or
setting a boolean/enum flag saying what the thread is doing, and have the main thread check on it every so often to make sure it hasn't been set to the error state.
This is code is completely off the top of my head, isn't that good, but will give you the general idea:
delegate void ThreadCrashedEvent();
Event ThreadCrashedEvent threadCrashed;
Thread th;
Main()
{
threadCrashed += OnThreadCrashed();
th = new thread(myfunction);
th.Start();
}
void OnThreadCrashed()
{
th = new thread(myfunction);
th.Start();
}
void myfunction()
{
while(true)
{
try
{
LetsGetDangerous();
}
catch(exception)
{
if(threadCrashed != null)
{
threadCrashed();
return;
}
}
}
I have a BackgroundWorker DoWork function as follows
private void WorkerGetFeedData(object sender, DoWorkEventArgs args)
{
_feed.FetchUserData(_userNameCollection);
}
The FetchUserData is a function in another class(whose object is _feed) in another project in the same solution. The data fetch process takes considerable time and I'd like for the user to be able to cancel the process if necessary. How do I convey a cancel operation from the user to a function call elsewhere and just stop it?
You can use BackgroundWorker.CancelAsync method. Here's more info with example: MSDN
To be more exact to your problem, pass the worker to FetchUserData. It is the sender parameter. Then in the FetchUserData function you can check if the flag BackgroundWorker.CancellationPending is set and finish your method.
void FetchUserData(IEnumerable<Users> userNameCollection, BackgroundWorker worker)
{
// ...
if(worker.CancellationPending)
{
// Finish method..
}
}
And the WorkerGetFeedData method:
private void WorkerGetFeedData(object sender, DoWorkEventArgs args)
{
var worker = sender as BackgroundWorker;
if(worker != null)
_feed.FetchUserData(_userNameCollection, worker);
}
Send a message (event) to the worker thread that changes a boolean, indicating that the worker thread should end/cancel itself.
Edit: I was a bit quick reading your question, missing the important part. While trying to make up I found this interesting article which might help:
http://ondotnet.com/pub/a/dotnet/2003/02/18/threadabort.html
It does work when simulating a long running process with Thread.Sleep(), being at work I dont have time right now to write code to test it on a proper application/long running task.
class Program
{
static void Main(string[] args)
{
Thread thread = new Thread(new ThreadStart(Foo));
thread.Start();
Console.ReadKey();
thread.Abort(); // cause ThreadAbortException to be thrown
Console.ReadKey();
}
static void Foo()
{
try
{
while( true )
{
Console.WriteLine("Long running process...");
Thread.Sleep(100000);
}
}
catch( ThreadAbortException ex )
{
Console.WriteLine(ex.Message);
}
finally
{
Console.WriteLine("Thread Closing ...");
}
}
}
The problem with this approach is - it uses Thread.Abort() - which interrupts the thread no matter what it is doing. This can lead to left open handles, memory leaks, etc. So while it may help it would most likely be very unwise to use.
Ian Griffiths supposes that another way to (force) cancel a thread would be to run it in its own, seperate process: http://www.interact-sw.co.uk/iangblog/2004/11/12/cancellation which you can kill whenever without affecting your process's internal state.
In case of BackgroundWorker, a cancel can be reported by the e.Cancel - property of the DoWork - event handler.
How can I achieve the same thing with a Thread object?
Here is a full example of one way of doing it.
private static bool _runThread;
private static object _runThreadLock = new object();
private static void Main(string[] args)
{
_runThread = true;
Thread t = new Thread(() =>
{
Console.WriteLine("Starting thread...");
bool _localRunThread = true;
while (_localRunThread)
{
Console.WriteLine("Working...");
Thread.Sleep(1000);
lock (_runThreadLock)
{
_localRunThread = _runThread;
}
}
Console.WriteLine("Exiting thread...");
});
t.Start();
// wait for any key press, and then exit the app
Console.ReadKey();
// tell the thread to stop
lock (_runThreadLock)
{
_runThread = false;
}
// wait for the thread to finish
t.Join();
Console.WriteLine("All done.");
}
In short; the thread checks a bool flag, and keeps runing as long as the flag is true. I prefer this approach over calling Thread.Abort becuase it seems a bit nicer and cleaner.
Generally you do it by the thread's execute being a delegate to a method on an object, with that object exposing a Cancel property, and the long-running operation periodically chercking that property for tru to determine whether to exit.
for example
public class MyLongTunningTask
{
public MyLongRunninTask() {}
public volatile bool Cancel {get; set; }
public void ExecuteLongRunningTask()
{
while(!this.Cancel)
{
// Do something long running.
// you may still like to check Cancel periodically and exit gracefully if its true
}
}
}
Then elsewhere:
var longRunning = new MyLongTunningTask();
Thread myThread = new Thread(new ThreadStart(longRunning.ExecuteLongRunningTask));
myThread.Start();
// somewhere else
longRunning.Cancel = true;
A blocked thread can be stopped prematurely in one of two ways:
Thread.Interrupt
Thread.Abort
The main question is if the thread works on any ressources which need to be released correctly - in this case - you need to work with a property on the actual object which runs the thread.
There's Thread.Abort, which works by injecting a ThreadAbortException into the thread. It's a little risky because:
Your thread can get stuck if it's executing native code at the time
The code in the thread better be exception-safe, because this ThreadAbortException could happen on any line of code within it, even something innocent like i = i + 1
You're better off coding your own signalling mechanism between your GUI thread and the background thread. It's hard to recommend something without knowing what's going on inside that thread, but where I have a thread that works by waiting on some object in a loop, I use an AutoResetEvent and wait on that too.