Jeff Hornby
Jeff Hornby

Reputation: 13680

Can I stop a System.Threading.Timer

I have an application that uses timers to occasionally run monitoring tasks on secondary threads. Some of these cleanup tasks take a lot of time and I would like to be able to abort these tasks (gracefully if possible) when my user ends the program.

Is there any way to abort the thread programatically as I can with Thread.Abort(), or would I have to add a flag to the code to indicate that the thread has finished and check for that in valrious places in the code that is started by the timer?

Upvotes: 6

Views: 13991

Answers (5)

e-info128
e-info128

Reputation: 4092

public void stopTimer(){
    myThreadingTimer = null;
}

Explication: Destroy object = destroy proccess.

Upvotes: -1

sizar surani
sizar surani

Reputation: 69

use this.Timer.Change(Timeout.Infinite, Timeout.Infinite); first i have use .dispose method but it does not work in my case so i have use Timer.change.

this is the best solution i have find.

Upvotes: 4

Nicholas Carey
Nicholas Carey

Reputation: 74375

You mean something along these lines?

using System;
using System.Threading ;

class AppCore : IDisposable
{
    Timer    TimerInstance ;
    string[] Args          ;

    public AppCore( string[] args )
    {
        if ( args == null ) throw new ArgumentNullException("args") ;
        this.TimerInstance   = new Timer( Tick , null , new TimeSpan(0,0,30) , new TimeSpan(0,0,15) ) ;
        this.Args            = args ;
        this.Cancelled       = false ;
        this.Disposed        = false ;
        return ;
    }

    public int Run()
    {
        // do something useful
        return 0 ;
    }

    private bool Cancelled ;
    public void Cancel()
    {
        lock( TimerInstance )
        {
            Cancelled = true ;
            TimerInstance.Change( System.Threading.Timeout.Infinite , System.Threading.Timeout.Infinite ) ;
        }
        return ;
    }

    private void Tick( object state )
    {
        if ( !Cancelled )
        {
            // do something on each tick
        }
        return ;
    }

    private bool Disposed ;
    public void Dispose()
    {
        lock ( TimerInstance )
        {
            if ( !Disposed )
            {
                using ( WaitHandle handle = new EventWaitHandle( false , EventResetMode.ManualReset ) )
                {
                    TimerInstance.Dispose( handle ) ;
                    handle.WaitOne() ;
                }
                Disposed = true ;
            }
        }
        return ;
    }

}

Upvotes: 1

Bradley Uffner
Bradley Uffner

Reputation: 17001

You can stop the timer before it's callback executes using .change, but once the callback starts executing you should use an application level flag to allow your code to exit.

As a side note, you shouldn't use thread.abort() unless you are absolutely 100% sure that you know the state it is going to be left in. it can seriously destabilize your application in strange ways.

Upvotes: 5

JaredPar
JaredPar

Reputation: 755557

There is no way to know the Thread on which a Threading.Timer callback will run ahead of time. Hence there is no general way to abort it. It is possible to have the callback itself communicate the Thread instance but it opens up a couple of race conditions

Note: In general using Abort is a bad practice. It's a fairly reliable way to end up with hard to detect deadlocks and / or resource leaks. It's much better to use a passive mechanism like CancellationToken

Upvotes: 4

Related Questions