1

How can I restrict timer thread execution time? I have long running timer work that should work no more than 30 seconds.

kseen
  • 359
  • 8
  • 56
  • 104
  • You can't directly do that - do you have some kind of loop somewhere that you can check the elapsed time,inside the thread itself? – Shadow The GPT Wizard Nov 10 '11 at 10:54
  • Not duplicate, but related: http://stackoverflow.com/questions/299198/implement-c-sharp-generic-timeout – Shadow The GPT Wizard Nov 10 '11 at 10:55
  • @ShadowWizard I don't have that loop in timer thread, any ideas? – kseen Nov 10 '11 at 10:58
  • Try the code in the accepted answer to the linked question – Shadow The GPT Wizard Nov 10 '11 at 11:04
  • 1
    What's the reason for restricting the thread's executing time? Surely if you want to execute a task on another thread, you would normally leave it to finish it's execution. If you are waiting for an operation to complete and want some form of time-out on that operation, then killing the thread forcefully after a period of time is not the most graceful of ways to go about it. – Samuel Slade Nov 10 '11 at 11:06

2 Answers2

1

The only way to do this is to have a second thread (possibly the one that created the worker thread) monitor and then kill it or gracefully call it to quit immediately. Killing threads you should avoid, and only use as the last resort. Here is example how:

        Thread t = new Thread(myLongThreadProc);
        t.Start();
        Thread.Sleep(30000);
        t.Abort();

By 'gracefully call it to quit', I mean to set some stop variable to some value, and give the thread some short time to quit itself, otherwise you kill it. But it is the design of your thread function to make it actually quit. Here is the sample code:

        Thread t = new Thread(myLongThreadProc);
        threadRun = true;
        t.Start();
        Thread.Sleep(30000);
        threadRun = false; //this variable is monitored by thread
        if (!t.Join(1000))  //inside your thread, make sure it does quit in one second
        {                   //when this variable is set to false
            t.Abort();
        }

And should I mention that your caller thread does not have to sleep for 30 seconds, but you can use a timer instead (if it is a form thread) or do something useful and check periodically - or have a third worker thread just counting 30 seconds...

zmilojko
  • 2,125
  • 17
  • 27
  • No need to spin up a separate thread for this. That's a huge waste of resources. And if the thread that started the background thread was going to wait for exit, why start a thread at all? You're better off using a one-shot timer, and having the callback function signal the other thread to stop. – Jim Mischel Nov 11 '11 at 23:01
1

Just have your worker method start a 30-second timer and check to see if it's elapsed as your worker does its thing:

    bool timerElapsed;

    public void DoWork()
    {
        timerElapsed=false;
        System.Timers.Timer timer = new System.Timers.Timer(30000);
        timer.Elapsed += new System.Timers.ElapsedEventHandler(timer_Elapsed);
        timer.Start();

        while (true)
        {
            if (timerElapsed)
            {
                // handle 30-sec elasped error
                break;
            }
            // continue doing work and break when done
        }
        timer.Stop();
    }

    void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
    {
        timerElapsed = true;
    }
Ed Power
  • 8,310
  • 3
  • 36
  • 42
  • Why use a timer when you could just use `var sw = Stopwatch.StartNew()`, and then have your loop check `sw.ElapsedMilliseconds > 30000`? – Jim Mischel Nov 11 '11 at 23:05
  • @Mim Mischel - Checking elapsed time could work just as well (BTW, why don't you offer that as an answer?) However, if the OP's code is complex it may be simpler to relegate the elapsed check to a timer. – Ed Power Nov 14 '11 at 18:30