开发者

Can I dispose a Threading.Timer in its callback?

I'm using Threading.Timer, like:

new Timer(new TimerCallback(y=>
{
    try
    {
        Save(Read(DateTime.Now));
        // here i want to dispose this timer
    }
    catch
    {                          
    }
}),null,100000,10000);

How can I dispose this timer inside of a callback. or workaround? Update: Let me explain the situation. I want to try to call the method "Save", while it throws an exception. If it works, I need to stop the 开发者_开发百科timer.


Try this:

Timer timer = null;
timer = new Timer(new TimerCallback(y =>
{    
    try    
    {
        Save(Read(DateTime.Now));        
        // here i want to dispose this timer
        timer.Dispose();    
    }    
    catch    
    {    
    }
}));
timer.Change(10000, 10000);

EDIT:

I changed the above code slightly according to Chuu's suggestion. Note that if the TimerCallback is called simultanuously by different timer events, Timer.Dispose may end up being called several times. Luckily the Timer does not care if it is being disposed of several times.


Here's a better way to do this. When you use the constructor with only one param (TimerCallback), the state passed to the callback will be the timer itself.

Timer timer = new Timer(o =>
{
     ((Timer)o).Dispose();
     //Your code here     
});

//Start the timer
timer.Change(100000,10000);

Here is an example from the msdn docs :

public void StartTimer(int dueTime)
{
    Timer t = new Timer(new TimerCallback(TimerProc));
    t.Change(dueTime, 0);
}

private void TimerProc(object state)
{
    // The state object is the Timer object.
    Timer t = (Timer) state;
    t.Dispose();
    Console.WriteLine("The timer callback executes.");
}

http://msdn.microsoft.com/en-us/library/ms149618(v=vs.110).aspx


You need to keep the reference of the timer in a variable -

public class MyClass
{
    private Timer _timer;

    public void StartTimer()
    {
        _timer =  new Timer(new TimerCallback(y=>{
                            try
                            {
                                Save(Read(DateTime.Now));
                                _timer.Dispose();
                            }
                            catch { 

                            }
                        }),null,100000,10000);
    }



}

Note: This is untested code. Please check if it works and update.


You'll have to store a reference to the timer somewhere and pass that in as state to the timer object itself. Try creating a class something like this:

public class TimerContainer
{
  public Timer Timer { get; set; }
}

Then use it in your method like so:

Action<object> tcb = state =>
{
  var container = (TimerConatiner)state;
  try
  {
    Save(Read(DateTime.Now));
    container.Timer.Dispose();
  }
  catch
  {
    // whatever...
  }
};

var container = new TimerContainer();
container.Timer = new Timer(tcb, container, 100000, 10000);


Take care if you use multithreading or multitasking! if so, here you're the code and a solucion for a CancelAfter method extensor (.net 4.0):

       private static object syncObj = new object();

       public static void CancelAfter(this CancellationTokenSource source, int timeoutMilliseconds, Action code = null)
    {
        if (timeoutMilliseconds == 0) return; // No timeout

        if (source == null)
        {
            throw new NullReferenceException();
        }
        if (timeoutMilliseconds < -1)
        {
            throw new ArgumentOutOfRangeException("timeout");
        }
        Timer timer = new Timer(delegate(object self)
        {
            lock (syncObj)
            {
                try
                {
                    if (null != code)
                        code.Invoke();
                    source.Cancel();

                    ((IDisposable)self).Dispose();
                }
                catch (ObjectDisposedException)
                {
                }                   
            }
        });
        timer.Change(timeoutMilliseconds, -1);
    }
}

Regards, Juanlu, ElGuerre

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜