15

I'm looking for a way to restart a thread that has been stopped by Abort()..

public partial class MyProgram : Form
{
  private Thread MyThread = new Thread(MyFunction);
  private System.Windows.Forms.Button startStopBtn = new System.Windows.Forms.Button();
  public MyProgram()
  {
    MyThread.Start();
    startStopBtn += new EventHandler(doStop);
    startStopBtn.Text = "Stop";
  }
  private static void MyFunction()
  {
    // do something
  }
  private void doStop(object sender, EventArgs e)
  {
    MyThread.Abort();
    startStopBtn -= new EventHandler(doStop);
    startStopBtn += new EventHandler(doStart);
    startStopBtn.Text = "Start";
  }
  private void doStart(object sender, EventArgs e)
  {
    MyThread.Start(); // << Error returned when clicking the button for 2nd time
    startStopBtn -= new EventHandler(doStart);
    startStopBtn += new EventHandler(doStop);
    startStopBtn.Text = "Stop";
  }
}

Any idea?

Yana D. Nugraha
  • 5,069
  • 10
  • 45
  • 59

7 Answers7

37

Once you have aborted your thread, you cannot start it again.

But your actual problem is that you are aborting your thread. You should never use Thread.Abort().

If your thread should be paused and continued several times, you should consider using other mechanisms (like AutoResetEvent, for example).

[EDIT]

The simplest solution to abort a thread, as mentioned by Ian Griffiths in the link above, is:

The approach I always recommend is dead simple. Have a volatile bool field that is visible both to your worker thread and your UI thread. If the user clicks cancel, set this flag. Meanwhile, on your worker thread, test the flag from time to time. If you see it get set, stop what you're doing.

The only thing that you need to do to make it work properly, is to rearrange your background method so that it runs in a loop - so that you can periodically check if your flag has been set by a different thread.

If you need to have pause and resume functionality for the same worker thread, instead of the simple volatile bool flag approach, you could go for a slightly more complex approach, a synchronizing construct such as AutoResetEvent. These classes also provide a way to put the worker thread to sleep for a specified (or indefinite) amount of time between signals from the non-worker thread.

This thread contains a concrete example with Start, Pause, Resume and Stop methods. Note how Brannon's example never aborts the thread. It only fires an event, and then waits until the thread finishes gracefully.

Community
  • 1
  • 1
vgru
  • 49,838
  • 16
  • 120
  • 201
19

Simply add MyThread = new Thread(MyFunction) before calling MyThread.Start() in doStart(). Do not create the thread outside of your methods, the space there is thought for declarations.

Please note that killing a thread with thread.Abort() can be very dangerous, as it might cause unexpected behavior or might not correctly dispose resources owned by the thread. You should try to accomplish clean multi threading, like Groo described in his answer.

Emiswelt
  • 3,909
  • 1
  • 38
  • 56
  • This answer is more a workaround than a real answer. You don't even explain why he gets an error. Groo got it right. – Trap Jun 28 '09 at 17:11
  • 4
    You're right, but when i was a programming beginner, I had several similar problems. I was reading many solutions like that one from groo, and yes, you're completely right, my solution is only a workaround. But the mechanisms that groo describes were too complex for me to understand in my programming-newb times. So I thougt, it may be better to provide a simple "answer" (or workaround) for a programmer not so experienced. – Emiswelt Jun 28 '09 at 20:16
  • This is the stuff that makes bad programmers. They don't invest enough time to understand what they're doing. Who's going to clean up your Thread.Abort mess when you're gone? – NT_ Jul 28 '10 at 13:25
8

The simple answer is, you can't. Once a thread has been aborted, you can't restart it. Just create a method or something, that returns a Thread object just how you need it. When you need a new Thread, just get it from that method.

BFree
  • 102,548
  • 21
  • 159
  • 201
2

No, there isn't, but why would you want to? Just start up a new thread, with the same ThreadStart, and the same parameter (if any).

John Saunders
  • 160,644
  • 26
  • 247
  • 397
0

If you really need to interrupt the thread function and resume, you should set a condition and then check it periodically during processing.

That would allow you to stop processing for some amount of time and then resume.

I've used events and Wait calls to accomplish a similar task.

Brad Bruce
  • 7,638
  • 3
  • 39
  • 60
0

The easiest way is to not abort the thread.

Rhythmic Fistman
  • 34,352
  • 5
  • 87
  • 159
-3

I really don't understand why people provide information if they do not know that is correct.. How can a real programmer suspend or stop processing a thread for sometime and then release it and thereby making the code vulnerable... @Brad-- m sorry.. but your idea was not good.. @Rhythmic - You need to work on your way to approach things..

BFree was somewhat right if you people got him the same way he wanted to say.. You just need to re-declare that..

below is the example:

Public Shared Sub ResetAbort()

    Dim ThreadPleaseWait As New Thread(New ThreadStart(AddressOf YourSubName))

    YourThreadName.Start()

    Thread.Sleep(2000)

    YourThreadName.Abort()

End Sub

Now you can use this Sub anywhere you want to start the thread. It will automatically abort the thread.

If you want to start the thread on Button1_click() event and stop it on Button2_Click() event use this:

in Button1_click() event

    Dim ThreadPleaseWait As New Thread(New ThreadStart(AddressOf YourSubName))

    YourThreadName.Start()

in Button2_click() event

    YourThreadName.Start()

doing this way you will abort you thread where ever you want and will initialize it again. You can also use YourThreadName.ThreadState.Running property to check if the thread is running or not(Just to avoid multiple instances of the same thread.....

Sands
  • 1
  • 6
    Please fix your formatting. Also, while you are editing it, you might want to make it a little less belligerent. While you don't like the word "no", you *cannot restart an aborted thread*. What OP asked is not possible. Also, Thread.Abort() is considered harmful. There are much better ways to control thread execution. You don't serve the asker by letting him continue to do bad things. Better to give alternatives that serves his requirements without incurring the same risk. –  Jun 28 '11 at 13:48