views:

377

answers:

3

Hello!

I have this code:

Thread t = new Thread(() => UpdateImage(origin));
t.Name = "UpdateImageThread";
t.Start();

This code is created on a Custom Control. I want to stop this thread (if it's running) when the object is going to be dispose.

This custom control has the following method:

void IDisposable.Dispose()
{
   /* My own code */
   base.Dispose(true);
}

I think this is the place to put the code but:

How can I know is the thread is running? How can I take a referece for the thread and stop it?

By the way, UpdateImage call a web service, so I think that it's waiting all of its life. How can I finish this wait?

Thank you!

+1  A: 

It depends a lot on what UpdateImage() does and how well it copes with the Image being disposed while it it still active. If UpdateImage() is your code and contains a loop you can tell it to stop (using a field like _stopping). If not, the best thing may be to do nothing - in the rare case of Disposing the control while the image is still updating you take the penalty of leaving it to the GC.

About how to get the Thread: By saving the reference when and where you create it, for instance int the private member _updateThread.

Now actually stopping (aborting) the thread is a (very) bad idea.

So you'll need an indicator, like

private bool _stopping = false;

And it is up to the UpdateImage() method to react to _stopping == true and stop with what it is doing.

Your Dispose() can then use

_stopping = true;
_updateThread.Join()
Henk Holterman
UpdateImage method does a Web Service Request and I don't know how to abort it. Maybe doing it asynchronous...
VansFannel
A: 

I suggest to override the Dispose method in your Custom Control. There you have the reference of your thread and you can call .Join() for example...

SuperPro
+1  A: 

Save your thread variable 't' so that you can re-use it later.

Within your Dispose method you want something like:

void IDisposable.Dispose()
{
   if(t.IsRunning)
   {
      cancelThreads = true;  // Set some cancel signal that the thread should check to determine the end
      t.Join(500); // wait for the thread to tidy itself up
      t.Abort(); // abort the thread if its not finished
   }
   base.Dispose(true);
}

You should be careful aborting threads though, ensure that you place critical section of code within regions that won't allow the thread to stop before it has finished, and catch ThreadAbortExceptions to tidy anything up if it is aborted.

You can do something like this in the threads start method

public void DoWork()
{
   try
   {  
      while(!cancelThreads)
      {
         // Do general work

         Thread.BeginCriticalRegion();
           // Do Important Work
         Thread.EndCriticalRegion(); 
      }
    }
    catch(ThreadAbortException)
    {
      // Tidy any nastiness that occured killing thread early    
    }
}
Ian
And... what about to abort web service request?
VansFannel
IsRunning, BeginCriticalRegion and EndCriticalRegion are not compatible with Compact Framework 2.0.
VansFannel
My Apologies, I didn't spot the compact part. Oops. In that case simply have a flag which you set for each thread (you might need a custom wrapper class to do this). The Begin and End critical regions, well simply make sure you ensure everything critical is valid in the ThreadAbortException.
Ian