4

I have an user control which include timer. When timer event run, it will call some threads.

User Control

class MyControl
{
    public Timer iTime
    {
        get;
        set;
    }

    Timer tmr;

    public MyControl
    {
    tmr = new Timer();
    }

    // Some Properties
}
}

Main Form

class MyForm
{
     Thread thd;

     MyControl cls = new MyClass();
     cls.iTime.Tick += new EventHandler(iTime_Tick);

     void iTime_Tick(object sender, EventArgs e)
     {
         thd = new Thread(delegate() { doWork(1); });
         thd.Start();

         thd = new Thread(delegate() { doOtherJob(); });
         thd.Start();
     }

     delegate void notif(int Param1);

     void Job(int Param1)
     {
         if (this.InvokeRequired) 
         {
            notif handler = new notif(notifParam);
            this.Invoke(handler, new object[] { Param1 });
         }
         else
         {
        // Other Process
         }
     }

     private void Logout()
     {
        cls.iTime.Stop();
        cls.iTime.Enabled = false;
        cls.iTime.Tick -= new EventHandler(iTime_Tick);

        thd.abort();
        thd.join();
     }
}

How to terminate thread in timer ? When I unsubscribe timer event even close form, the threads still run.

Blishton
  • 109
  • 2
  • 9
  • 3
    Threads you have created won't stop just because you unsubscribe an event. You won't get any *new* threads, but existing threads will just keep going. Your existing code will create two new threads for every timer tick - that's potentially a lot of threads! Is that your intention? – Dan Puzey Sep 13 '13 at 14:55
  • @Dan Puzey: Sorry I forgot about thread.Abort(); and thread.Join(); but still run even I call form dispose. – Blishton Sep 13 '13 at 15:01

1 Answers1

2

Disposing the form has no effect on your threads.

Your code is clearly incomplete (for example MyControl cls = new MyClass();, and we have no idea what doWork or doOtherJob are), but I suspect part of the problem is that you only have a single thread variable.

Every time the timer ticks, you do thd = new Thread twice. If your timer ticks ten times then thd is pointing at your most recent thread, but there are potentially 19 other threads still running, and any of those might be keeping your application alive.

One thing that might help is explicitly setting .IsBackground to true on the threads you create, since that will encourage them to terminate when your UI thread closes. However, I'd advise that creating this many threads in this way is likely not an efficient model, and you'd be better off revising your design to run just one or two worker threads, instead of kicking of dozens.

Dan Puzey
  • 33,626
  • 4
  • 73
  • 96
  • Agreed with Dan. You are loosing the first ref to thd when you start the 2nd thread and assign it to thd, so you can't abort it. Threads are function calls (your doWork and doOtherJob) when the function ends the thread ends. The proper method to terminate a thread is to govern its execution with a sentinel variable, either passed into the function delegate or a shared local variable. You have to keep checking the sentinel in your thread delegate and break out when it is set. – Sean B Sep 13 '13 at 15:13
  • If I make new thread instance in timer (thdSecond = new thread(delegate() { doWork(1);), is it traceable and can be Abort()? – Blishton Sep 13 '13 at 18:32
  • Yes, but then when your timer fires again you'll overwrite it, and you'll no longer be able to abort it. – Dan Puzey Sep 16 '13 at 09:22