Поточно-безопасное выполнение с использованием System.Threading.Timer и Monitor

Использование System.Threading.Timer приводит к тому, что потоки запускаются из ThreadPool , что означает, что интервал выполнения для таймера истекает, пока поток все еще обрабатывает по порядку предыдущего запроса, то тот же обратный вызов будет делегирован для выполнения в другом потоке. Это, очевидно, вызовет проблемы в большинстве случаев, если обратный вызов не будет знать о повторном входе, но мне интересно , как сделать это наилучшим (то есть безопасным) способом.

Допустим, у нас есть следующее:

ReaderWriterLockSlim OneAtATimeLocker = new ReaderWriterLockSlim();

OneAtATimeCallback = new TimerCallback(OnOneAtATimeTimerElapsed);
OneAtATimeTimer = new Timer(OneAtATimeCallback , null, 0, 1000);

Если весь шебанг будет заблокирован, как таковой:

private void OnOneAtATimeTimerElapsed(object state)
{
    if (OneAtATimeLocker.TryEnterWriteLock(0))
    {
        //get real busy for two seconds or more

        OneAtATimeLocker.ExitWriteLock();
    }
}

Или следует управлять только входом и выгнать «нарушителей» как таковых: используется для регистрации контроллеров, теперь не рекомендуется:

public class WindsorControllerFactory : DefaultControllerFactory
{
    IWindsorContainer container;

    public WindsorControllerFactory()
    {
        container = new WindsorContainer(new XmlInterpreter(new ConfigResource("castle")));

        // register all the controller types as transient
        var controllerTypes = from t in Assembly.GetExecutingAssembly().GetTypes()
                              where typeof(IController).IsAssignableFrom(t)
                              select t;

        //[Obsolete("Use Register(Component.For<I>().ImplementedBy<T>().Named(key).Lifestyle.Is(lifestyle)) instead.")]
        //IWindsorContainer AddComponentLifeStyle<I, T>(string key, LifestyleType lifestyle) where T : class;
        foreach (Type t in controllerTypes)
        {
            container.Register(Component.For<IController>().ImplementedBy<???>().Named(t.FullName).LifeStyle.Is(LifestyleType.Transient));
        }
    }

    // Constructs the controller instance needed to service each request
    protected override IController GetControllerInstance(Type controllerType)
    {
        return (IController)container.Resolve(controllerType);
    }
}

Новое предложение - использовать Register (Component.For () .ImplementedBy () .Named (key) .Lifestyle.Is (lifestyle)) , но я не могу понять, как представить реализующий тип контроллера в методе ImplementedBy () . Я пробовал ImplementedBy () и ImplementedBy () , но не могу найти подходящий способ передать тип реализации. Есть идеи?

8
задан Kiril 26 February 2011 в 07:57
поделиться