Search code examples
c#multithreadingtimerdispose

c# System.Threading.Timer wait for dispose


I have a class which uses a Timer. This class implements IDispose. I would like to wait in the Dispose method until the timer will not fire again.

I implement it like this:

private void TimerElapsed(object state)
{
    // do not execute the callback if one callback is still executing
    if (Interlocked.Exchange(ref _timerIsExecuting, 1) == 1) 
        return;

    try
    {
        _callback();
    }
    finally
    {
        Interlocked.Exchange(ref _timerIsExecuting, 0);
    }
}

public void Dispose()
{
    if (Interlocked.Exchange(ref _isDisposing, 1) == 1)
        return;

    _timer.Dispose();

    // wait until the callback is not executing anymore, if it was
    while (_timerIsExecuting == 0) 
    { }

    _callback = null;
}

Is this implementation correct? I think it mainly depends on the question if _timerIsExecuting == 0 is an atomic operation. Or would I have to use a WaitHandle. For me it seems it would make the code unnecessarily complicated...

I am not an expert in multi-threading, so would be happy about any advice.


Solution

  • Unless you have a reason not to use System.Threading.Timer This has a Dispose method with a wait handle

    And you can do something like,

    private readonly Timer Timer;
    private readonly ManualResetEvent TimerDisposed;
    public Constructor()
    {
        Timer = ....;
        TimerDisposed = new ManualResetEvent(false);
    }
    
    public void Dispose()
    {
        Timer.Dispose(TimerDisposed);
        TimerDisposed.WaitOne();
        TimerDisposed.Dispose();
    }