Таймер внутри синглтона WCF, размещенного в службе Windows (через webHttpBinding), неожиданно отключается - PullRequest
2 голосов
/ 14 августа 2011

У меня есть служба WCF, размещенная в службе Windows (работает в локальной системе).Я использую System.Timer внутри.Операция o1 , которая инициализирует таймер, объявляется через конечную точку http через webHttpBinding.Я включил трассировку для System.ServiceModel и из файла .svcLog проверил продолжительность прослушивания для операции o1.Это показывает, что после работы в течение примерно 20 часов прослушивание в конечной точке http просто прекращается.

Я думаю, что это связано с тем, что в эту конечную точку не поступило входящее сообщение.Проблема здесь в том, что когда прослушивание останавливается, мой таймер (который был инициализирован внутри этой конкретной операции o1 ) также останавливается!

Есть ли рекомендуемый способ сохранить слушателя, иотсюда таймер, на длительное время?Можем ли мы периодически пинговать Операцию o1, чтобы сохранить ее в памяти?

Кроме того, моя переменная таймера, которую я инициализирую внутри Операции o1, является переменной экземпляра, разве эта переменная не должна находиться в памяти (WCF являетсяSingleton), даже если слушатель закрывается ??

Большое спасибо.

Код Exceprts-

[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple, InstanceContextMode = InstanceContextMode.Single)]
public class SchedulerWindows : ISchedulerWindows
{
    ///.........all instance variables.....
    DataTimer timer = null; /**DataTimer wraps a System.Timers timer variable**/
    public List<DataTimer> timersInService = new List<DataTimer>();
    public ISchedulerWindows.o1(string s1, string s2, /*********/)
    {
     //..........//
     timer = new DataTimer();
    }
}

public class DataTimer
    {

        /****Newly introduced System.Threading.Timer, previously I was using        System.Timers.Timer which was dying****/

        public System.Threading.Timer thTimer;
        private static readonly object dbAccessLock = new object();
        private static readonly object thCallbackLock = new object();

        public DataTimer()
        {
        }

        public DataTimer(/************/)
        {            
            TimerCallback timerDelegate = new TimerCallback(this.WorkMethod);
            EventLogLogger l = new EventLogLogger();
            //l.LogMessage("setting up timer ");
            thTimer = new Timer(this.WorkMethod, null, 0, period);
        }
...
}

РЕДАКТИРОВАТЬ: Изменение на систему.Потоковое пространство имен из пространства имен System.Timers И увеличение временного интервала исправили это для меня.Переменная таймера больше не исчезает.

Ответы [ 2 ]

1 голос
/ 15 августа 2011

Наиболее вероятная причина вашей проблемы: InstanceContextMode . Если вы хотите, чтобы ваш экземпляр службы всегда был в памяти, вы должны использовать Single. Вероятно, у вас есть PerSession или PerCall, и это объясняет, почему ваш таймер исчезает. Вы упоминаете, что ваше обслуживание одноразовое, но симптомы очень подозрительные. Экземпляр службы остается в памяти до тех пор, пока вы не выключите хост.

[ServiceBehavior(
         ConcurrencyMode = ConcurrencyMode.Multiple, 
         InstanceContextMode = InstanceContextMode.Single
)]

Из Управление экземплярами WCF :

Служба синглтона живет вечно и уничтожается только один раз Хозяин отключается. Синглтон создается ровно один раз, когда хост создан.

РЕДАКТИРОВАТЬ: Вы, вероятно, проверили, что служба Windows все еще работает, когда ваш слушатель прекращает слушать и таймер исчезает. Также имеет смысл посмотреть, останется ли сам ServiceHost в памяти. Вы также можете поместить некоторые записи в обработчики событий ServiceHosts «Закрытие», «Закрытие» и «Ошибка».

РЕДАКТИРОВАТЬ 2: Если ваш таймер исчезает, вы должны посмотреть, как вы его распределяете. Скорее всего, он получает мусор. Вы должны объявить его как поле экземпляра, доступное из живых объектов. Сделайте это статичным, чтобы быть абсолютно уверенным. Вы делаете это для DataTimer, но не ясно, как таймер объявлен и размещен внутри DataTimer. Напишите какой-нибудь код, пожалуйста.

РЕДАКТИРОВАТЬ 3: Вы не должны создавать таймеры в операции. Что произойдет, если операция вызывается более одного раза? Что происходит со старым таймером? Я не вижу, как вы закрываете / распоряжаетесь этим. У вас также есть два конструктора для DataTimer. Один из них ничего не делает. И помимо этого у вас есть отдельный список таймеров. Это немного запутанно. Пожалуйста, изолируйте проблему и, возможно, опубликуйте новый код после этого.

0 голосов
/ 15 августа 2011

Я не сталкивался с этой проблемой специально - однако, если вы просто хотите, чтобы таймер работал во время работы службы, почему бы не сделать его статичным.Тогда контекстный режим вашего экземпляра и время жизни экземпляра не повлияют на вашу функциональность.

...