public class HandlersRefresher
{
    private readonly IFiber dispatcherFiber;
    private const int HandlersUninitializedValue = -1;
    private int idealNumberOfHandlers = HandlersUninitializedValue;
    private static readonly ILog log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
    public const int RefreshIntervalInMs = 30*1000;
    public const int TimeToFirstCheckInMs = 10*1000;
    private readonly Action<bool> refreshMatchersAction;
    private ITimerControl timerControl = null;

    public HandlersRefresher(
         IFiber dispatcherFiber,
         Action<bool> refreshMatchersAction)
    {
        if (dispatcherFiber == null)
            throw new ArgumentNullException("dispatcherFiber");

        if (refreshMatchersAction == null) 
            throw new ArgumentNullException("refreshMatchersAction");

        this.dispatcherFiber = dispatcherFiber;
        this.refreshMatchersAction = refreshMatchersAction;
    }

    public int CurrentIdealNumberOfHandlers
    {
        get { return this.idealNumberOfHandlers; }
    }

    public void InspectHandlers(IFrameHandler[] handlers)
    {
        var numberOfHandlers = handlers == null ? 0 : handlers.Length;

        ScheduleRefreshIfNotAlreadyScheduled();

        if (numberOfHandlers > 0 && numberOfHandlers >= idealNumberOfHandlers) 
        {
            log.DebugFormat("Ustawianie idealnej liczby procedur obsugi na {0}", numberOfHandlers);
            idealNumberOfHandlers = numberOfHandlers;
        }
    }

    private void CancelRefreshSchedulingIfExists()
    {
        if (timerControl == null)
            return;

        log.Debug("Zatrzymywanie zaplanowanego odwieania procedur obsugi");

        timerControl.Cancel();
        timerControl = null;
    }

    private void ScheduleRefreshIfNotAlreadyScheduled()
    {
        if (timerControl != null)
            return;

        log.DebugFormat("Planowanie odwieania procedur obsugi co {0} ms.", RefreshIntervalInMs);
        timerControl = dispatcherFiber.ScheduleOnInterval(
           () => refreshMatchersAction(false), 
              TimeToFirstCheckInMs,
              RefreshIntervalInMs);
    }
}

