Подтвердить что ты не робот

Использование таймера в службе Windows

У меня есть служба Windows, в которой я хочу создать файл каждые 10 секунд.

У меня появилось много отзывов о том, что лучшим вариантом будет Timer в службе Windows.

Как я могу это достичь?

4b9b3361

Ответ 1

Во-первых, выберите правильный тип таймера. Вы хотите либо System.Timers.Timer, либо System.Threading.Timer - не использовать один, связанный с инфраструктурой пользовательского интерфейса (например, System.Windows.Forms.Timer или DispatcherTimer).

Таймеры обычно простые

  • установить интервал тика
  • Добавить обработчик события Elapsed (или передать ему обратный вызов при построении),
  • При необходимости запустите таймер (разные классы работают по-разному)

и все будет хорошо.

Примеры:

// System.Threading.Timer sample
using System;
using System.Threading;

class Test
{
    static void Main() 
    {
        TimerCallback callback = PerformTimerOperation;
        Timer timer = new Timer(callback);
        timer.Change(TimeSpan.Zero, TimeSpan.FromSeconds(1));
        // Let the timer run for 10 seconds before the main
        // thread exits and the process terminates
        Thread.Sleep(10000);
    }

    static void PerformTimerOperation(object state)
    {
        Console.WriteLine("Timer ticked...");
    }
}

// System.Timers.Timer example
using System;
using System.Threading;
using System.Timers;
// Disambiguate the meaning of "Timer"
using Timer = System.Timers.Timer;

class Test
{
    static void Main() 
    {
        Timer timer = new Timer();
        timer.Elapsed += PerformTimerOperation;
        timer.Interval = TimeSpan.FromSeconds(1).TotalMilliseconds;
        timer.Start();
        // Let the timer run for 10 seconds before the main
        // thread exits and the process terminates
        Thread.Sleep(10000);
    }

    static void PerformTimerOperation(object sender,
                                      ElapsedEventArgs e)
    {
        Console.WriteLine("Timer ticked...");
    }
}

У меня есть немного больше информации о этой странице, хотя я не обновлял это в течение длительного времени.

Ответ 2

Я бы не рекомендовал System.Timers.Timer, поскольку он молча ест необработанные исключения и, следовательно, скрывает ошибки, которые вы должны исправить. imho лучше, чтобы ваш код взорвался на вашем лице, если вы неправильно обрабатываете исключения.

Что касается System.Threading.Timer, я стараюсь использовать метод Change для запуска/остановки таймера в шаблоне следующим образом:

public class MyCoolService
{
    Timer _timer;

    public MyCoolService()
    {
        _timer = new Timer(MyWorkerMethod, Timeout.Infinite, Timeout.Infinite);
    }

    protected void OnStart()
    {
        _timer.Change(15000, Timeout.Infinte);
    }

    protected void MyWorkerMethod()
    {
        //pause timer during processing so it
        // wont be run twice if the processing takes longer
        // than the interval for some reason
        _timer.Change(Timeout.Infinite, Timeout.Infinite); 

        try
        {
            DoSomeWork();
        }
        catch (Exception err)
        {
            // report the error to your manager if you dare
        }

        // launch again in 15 seconds
        _timer.Change(15000, Timeout.Infinite);
    }

}

Ответ 3

Вот как вы это делаете просто

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using System.Timers;
using System.IO;

  namespace MyService
{
    public partial class Service1 : ServiceBase
    {
        Timer myTimer;
        int x = 0;
        public Service1()
         {
             InitializeComponent();
         }

         protected override void OnStart(string[] args)
         {

             myTimer = new Timer(10000);                                // Sets a 10 second interval
             myTimer.Elapsed +=new ElapsedEventHandler(myTimer_Elapsed);// Specifies The Event Handler
             myTimer.Enabled = true;                                    // Enables the control
             myTimer.AutoReset = true;                                  // makes it repeat
             myTimer.Start();                                           // Starts the interval




         }
         protected void myTimer_Elapsed(object sender, ElapsedEventArgs e)
         {
             // All the Cool code that you need to run eg. Making a new file every 10 seconds
             x++;
             StreamWriter myFile = new StreamWriter("MyFile" + x.ToString() + ".txt");
             myFile.Write("Something");
             myFile.Close();
         }
         protected override void OnStop()
         {
         }
     }
 }

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

Ответ 4

Это должен быть случай запуска System.Timers.Timer с правильным IntervalAutoReset установленным значением true) и обработкой Elapsed (но смотрите: обратный вызов не находится в каком-либо конкретном потоке).

В MSDN есть пример: http://msdn.microsoft.com/en-us/library/system.timers.timer.elapsed.aspx

также из MSDN:

Компонент Timer - это таймер на основе сервера, который позволяет вам указать повторяющийся интервал, в котором событие Elapsed было поднято в вашем приложении. Затем вы можете обработать это событие, чтобы обеспечить регулярную обработку. Например, предположим, что у вас есть критический сервер, который должен работать 24 часа в сутки, 7 дней в неделю. Вы можете создать службу, которая использует таймер для периодической проверки сервера и обеспечения готовности системы к работе. Если система не отвечает, служба может попытаться перезапустить сервер или уведомить администратора.

Серверный таймер предназначен для использования с рабочими потоками в многопоточной среде. Таймеры сервера могут перемещаться между потоками для обработки поднятого события Elapsed, что приводит к большей точности, чем таймеры Windows, во время всплытия события.

Ответ 6

полностью протестированное решение...

 using System;
    using System.Configuration;
    using System.ServiceProcess;
    using System.Timers;

    namespace SomeServices.WindowsService
    {
        public partial class SomeServicesWindowsService : ServiceBase 
        {
            private const int DefaultTriggerInterval = 5000;

            private readonly Timer _trigger;

            public SomeServicesWindowsService ()
            {
                InitializeComponent();
                _trigger = new Timer(GetTriggerInterval());
                _trigger.Elapsed += TriggerElapsed;
            }
            public bool ContinueTriggering { get; set; }

            public void TriggerElapsed(object sender, ElapsedEventArgs e)
            {
                var subject = (Timer)sender;
                subject.Stop();

                using (var service = new DeliveryServiceManager())
                {
                    service.ShouldContinue += service_ShouldContinue;
                    service.Run();
                }

                if (ContinueTriggering)
                    subject.Start();
            }

            void service_ShouldContinue(object sender, ShouldContinueEventArgs e)
            {
                e.Continue = ContinueTriggering;
            }

            public double GetTriggerInterval()
            {
                int interval;
                return int.TryParse(ConfigurationManager.AppSettings["triggerInterval"], out interval)
                    ? interval
                    : DefaultTriggerInterval;
            }

            protected override void OnStart(string[] args)
            {
                ContinueTriggering = true;
                _trigger.Start();
            }

            protected override void OnStop()
            {
                ContinueTriggering = false;
                _trigger.Stop();
            }
        }

        public class DeliveryServiceManager : IDisposable
        {
            public event EventHandler<ShouldContinueEventArgs> ShouldContinue;
            protected virtual void OnShouldContinue(ShouldContinueEventArgs e)
            {
                var handler = ShouldContinue;
                if (handler != null)
                {
                    handler(this, e);
                }
            }

            public void Dispose()
            {
                ShouldContinue = null;
            }

            public void Run()
            {
               //Iterate Something here.
                var eventArgs = new ShouldContinueEventArgs{Continue =  false};
                OnShouldContinue(eventArgs);
                if (!eventArgs.Continue)
                {
                    //Run step();        
                }
            }
        }

        public class ShouldContinueEventArgs : EventArgs
        {
            public bool Continue { get; set; }
        }
    }