Таймер в службе Windows требует перезагрузки - PullRequest
0 голосов
/ 23 августа 2011

Я создал службу Windows с таймером, в которой мне нужно установить интервал после каждого события Elapsed timer.Например, я бы хотел, чтобы он срабатывал каждый час по часам.

В Program.cs:

namespace LabelLoaderService
{
    static class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        /// 
        static void Main()
        {
#if (!DEBUG)
            ServiceBase[] ServicesToRun;
            ServicesToRun = new ServiceBase[] 
            { 
                new LabelLoader() 
            };
            ServiceBase.Run(ServicesToRun);
#else
            LabelLoader ll = new LabelLoader();
            ll.Start();
#endif

        }
    }
}

В LabelLoader.cs:

namespace LabelLoaderService
{
    public partial class LabelLoader : ServiceBase
    { 
       System.Timers.Timer timer = new System.Timers.Timer();

    public LabelLoader()
    {
        InitializeComponent();
        timer.Elapsed += new ElapsedEventHandler(timer_Elapsed);
    }

    protected override void OnStart(string[] args)
    {
        SetTimer();
    }


    public void Start()
    {
        // Debug Startup            
        SetTimer();
    }


    public void SetTimer()
    {
        DateTime nextRunTime = GetNextRunTime();
        var ts = nextRunTime - DateTime.Now;
        timer.Interval = ts.TotalMilliseconds;
        timer.AutoReset = true;  // tried both true & false
        timer.Enabled = true;
        GC.KeepAlive(timer);  // test - no effect with/without this line
    }

    void timer_Elapsed(object source, ElapsedEventArgs e)
    {
        timer.Enabled = false;
        // do some work here
        SetTimer();
    }

Если я установлю это на свой локальный компьютер, он правильно определит время следующего запуска и выполнится.Но это не работает в любое время после этого.Если я перезапускаю службу, она запускается в следующий запланированный раз, а затем снова ничего.Есть ли проблема, вызывающая SetTimer () в конце моей обработки, чтобы сбросить интервал и установить timer.Start ()?

1 Ответ

2 голосов
/ 23 августа 2011

используйте System.Threading.Timer вместо этого - по моему опыту это больше подходит для серверного использования ...

РЕДАКТИРОВАТЬ - согласно комментарию некоторый код / ​​подсказки:

ниже приведен очень простой способ избежать повторного входа (должен работать нормально в данном конкретном случае) - лучше было бы lock / Mutex или подобноесделать nextRunTime полем экземплярасоздать / начать свое время, например, с

// first the TimerCallback, second the parameter (see AnyParam), then the time to start the first run, then the interval for the rest of the runs
timer = new System.Threading.Timer(new TimerCallback(this.MyTimerHandler), null, 60000, 30000);

создайте свой обработчик таймера, похожий на

void MyTimerHandler (object AnyParam)
{
if ( nextRunTime > DateTime.Now) 
     return;

nextRunTime = DateTime.MaxValue; 
// Do your stuff here
// when finished do 
nextRunTime = GetNextRunTime();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...