0

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
        }


    }
Arianule
  • 8,811
  • 45
  • 116
  • 174
  • There are numerous options elencated in this question [How to wait for thread to finish with .NET?](http://stackoverflow.com/questions/1584062/how-to-wait-for-thread-to-finish-with-net) – Steve Jan 05 '13 at 11:20
  • 1
    @Steve I'm pretty sure that most people with no knowledge of Italian are unfamiliar with the meaning of *elencated*. Just sayin'. – Christoffer Lette Jan 05 '13 at 11:52
  • yeah, listed listed.... oh my...I need a little sugar to the brain. It 's time to have lunch – Steve Jan 05 '13 at 12:03

3 Answers3

2

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.

TomTom
  • 61,059
  • 10
  • 88
  • 148
1

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

Norbert Pisz
  • 3,392
  • 3
  • 27
  • 42
  • 1
    -1. Whow. Another one. See, there is a reason that one was marked in later versions as "do not use". Check http://www.interact-sw.co.uk/iangblog/2004/11/12/cancellation for an explanation - this is a method you should not ever call. It can have serious side effects. – TomTom Jan 05 '13 at 11:33
0

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();
prthrokz
  • 1,120
  • 8
  • 16
  • He already has it as volatile (as you can READ in his post). He merely does not want to the thread to finish. – TomTom Jan 05 '13 at 11:45
  • Well I cannot see the threadAlive variable declared using volatile keyword in the original post. Can you please point out ? :) Also, he wants the thread to stop instantly. And then restart it again. My answer just allows to do that. – prthrokz Jan 05 '13 at 11:57
  • Ups. overlooked that. yes. Sorry. My apologies. But technically it must not be a volatile, you can use an interlocked access. – TomTom Jan 05 '13 at 11:58
  • Yes, true interlocked can be use, but since the shared resource is simply a bool, volatile will serve the purpose. For more complex types like class or struct, interlocked or lock statement can serve the purpose. – prthrokz Jan 05 '13 at 12:00