Non-reentrant timers

后端 未结 5 461
别那么骄傲
别那么骄傲 2020-12-11 04:30

I have a function that I want to invoke every x seconds, but I want it to be thread-safe.

Can I set up this behavior when I am creating the timer? (I don\'t

5条回答
  •  醉梦人生
    2020-12-11 05:18

    Complementing Tim Lloyd's solution for System.Timers.Timer, here's a solution to prevent reentrancy for cases where you want to use System.Threading.Timer instead.

    TimeSpan DISABLED_TIME_SPAN = TimeSpan.FromMilliseconds(-1);
    
    TimeSpan interval = TimeSpan.FromSeconds(1);
    Timer timer = null; // assign null so we can access it inside the lambda
    
    timer = new Timer(callback: state =>
    {
      doSomeWork();
      try
      {
        timer.Change(interval, DISABLED_TIME_SPAN);
      }
      catch (ObjectDisposedException timerHasBeenDisposed)
      {
      }
    }, state: null, dueTime: interval, period: DISABLED_TIME_SPAN);
    

    I believe you don't want interval to be accessed inside of the callback, but that is be easy to fix, if you want to: Put the above into a NonReentrantTimer class that wraps the BCL's Timer class. You would then pass the doSomeWork callback in as a parameter. An example of such a class:

    public class NonReentrantTimer : IDisposable
    {
        private readonly TimerCallback _callback;
        private readonly TimeSpan _period;
        private readonly Timer _timer;
    
        public NonReentrantTimer(TimerCallback callback, object state, TimeSpan dueTime, TimeSpan period)
        {
            _callback = callback;
            _period = period;
            _timer = new Timer(Callback, state, dueTime, DISABLED_TIME_SPAN);
        }
    
        private void Callback(object state)
        {
            _callback(state);
            try
            {
                _timer.Change(_period, DISABLED_TIME_SPAN);
            }
            catch (ObjectDisposedException timerHasBeenDisposed)
            {
            }
        }
    
    
        public void Dispose()
        {
            _timer.Dispose();
        }
    }
    

提交回复
热议问题