how do you join / abort a group of dynamically created threads?

351 views Asked by At

I'm having some troubles with ending a group of dynamically created threads. The reason i need to end all these at any given point is so that i can refresh certain parts of my form and create new ones. Heres a simple scenario to show what happens in my threads.

A number of threads are created dynamically based upon certain variables inplace:

 for (int i = 0; i <= mDevices.Count; i++)
        {
            ThreadStart workerThread = delegate { pollDevices(mDevices[i - 2], this); };
            new Thread(workerThread).Start();
        }

  public void pollDevices(IDeviceInterface device, DeviceManager mainUI)
    {
       System.Timers.Timer timer = null;
        if (timer == null)
        {

            timer = new System.Timers.Timer(1000);
            timer.Elapsed += delegate(object sender, ElapsedEventArgs e) { timerElapsed(sender, e, device, mainUI); };

        }
        timer.Enabled = true;

 public void timerElapsed(object sender, ElapsedEventArgs e, IDeviceInterface device, DeviceManager mainUI)
    {


         device.connect(device, this);
        //wait till thread finishes and destroy
         Thread.CurrentThread.Abort();
    }

these threads then work off of a timer, and proc an event, which handles UI updates and such. however, when i try and refresh the UI (for example if any more entries in the database need taking into account) i get errors from deleting buttons on the form (these are assigned to a thread) if a thread is still running, so before i call for the refresh i need to stop all current threads in this manner.

so my question is, how can i abort this group of threads before i refresh my UI?

3

There are 3 answers

1
Brian Gideon On BEST ANSWER

You have several problems.

  • You are closing over a loop variable.
  • You are creating a thread for the sole purpose of starting a timer...why not just start the timer in the main thread?
  • Your timer instance is not rooted so it is possible that it will be eligible for garbage collection before you are done with it.
  • The System.Timers.Timer event handler will be executed on a ThreadPool thread (at least in this case) so trying to abort one of these threads is not going to end well.

There are enough problems here that you are going to do some significant restructuring before we can answer your main question. One additional tip though...do not try to access or manipulate any UI elements from a thread other than the main UI thread.

2
Jackie Weng On

Why are you using a timer within your thread proc?

ManualResetEvent exit = new ManualResetEvent(false);
for (int i = 0; i <= mDevices.Count; i++)
    {
        ThreadStart workerThread = delegate { pollDevices(mDevices[i - 2], this, exit); };
        new Thread(workerThread).Start();
    }

public void pollDevices(IDeviceInterface device, DeviceManager mainUI, ManualResetEvent exit)
{
    while(!exit.WaitOne(1000))
    {
         // do work
         device.connect(device, this);
    }
}

Then if you want to stop all threads, just call exit.Set()

1
Dave Lawrence On

I use this in one of my solutions http://msdn.microsoft.com/en-us/magazine/cc163644.aspx

It's the AbortableThreadPool. Might work for you.

Also a little confused as to why you call Thread.Abort in timerElapsed on a thread that's finishing anyway