wake-up-neo.com

Verwendung des Timers im Windows-Dienst

Ich habe einen Windows-Dienst, bei dem ich alle 10 Sekunden eine Datei erstellen möchte.

Ich habe viele Bewertungen, dass Timer im Windows-Dienst die beste Option wäre.

Wie kann ich das erreichen?

19
Parth Bhatt

Wählen Sie zunächst den richtigen Timer aus. Sie möchten entweder System.Timers.Timer oder System.Threading.Timer - verwenden Sie kein UI-Framework (z. B. System.Windows.Forms.Timer oder DispatcherTimer).

Timer sind im Allgemeinen einfach

  1. stellen Sie das Tick-Intervall ein
  2. Fügen Sie dem Ereignis Elapsed einen Handler hinzu (oder übergeben Sie ihm einen Rückruf bei der Erstellung).
  3. Starten Sie den Timer bei Bedarf (verschiedene Klassen arbeiten unterschiedlich)

und alles wird gut.

Proben:

// 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...");
    }
}

Ich habe ein bisschen mehr Informationen auf dieser Seite , obwohl ich das schon lange nicht mehr aktualisiert habe.

31
Jon Skeet

Ich würde System.Timers.Timer nicht empfehlen, da es unbehandelte Ausnahmen stillschweigend verarbeitet und daher Fehler verbirgt, die Sie beheben sollten. imho besser, dass Ihr Code in Ihrem Gesicht explodiert, wenn Sie Ausnahmen nicht richtig behandeln.

Bei System.Threading.Timer verwende ich normalerweise die Methode Change, um den Timer in einem Muster wie dem folgenden zu starten/stoppen:

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);
    }

}
12
jgauffin

So machen Sie es einfach

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()
         {
         }
     }
 }

Der obige Code ist der gesamte Service mit dem Timer. Mir ist klar, dass dies ein alter Beitrag ist, aber ich habe Stunden gebraucht, um das herauszufinden. Hoffentlich hilft es jemandem da draußen.

3
iuppiter

Dies sollte nur der Fall sein, wenn ein System.Timers.Timer mit der rechten Interval (und AutoReset auf true) gestartet wird und Elapsed behandelt wird (aber aufgepasst; der Rückruf ist nicht in einem bestimmten Thread).

MSDN hat ein Beispiel: http://msdn.Microsoft.com/en-us/library/system.timers.timer.elapsed.aspx

auch von MSDN:

Die Timer-Komponente ist ein serverbasierter Timer, mit dem Sie ein wiederkehrendes Intervall angeben können, in dem das Elapsed-Ereignis in Ihrer Anwendung ausgelöst wird. Sie können dieses Ereignis dann bearbeiten, um eine regelmäßige Verarbeitung bereitzustellen. Angenommen, Sie verfügen über einen kritischen Server, der rund um die Uhr an sieben Tagen in der Woche laufen muss. Sie können einen Dienst erstellen, der einen Zeitgeber verwendet, um den Server in regelmäßigen Abständen zu überprüfen und sicherzustellen, dass das System in Betrieb ist. Wenn das System nicht antwortet, kann der Dienst versuchen, den Server neu zu starten oder einen Administrator zu benachrichtigen.

Der serverbasierte Timer ist für die Verwendung mit Arbeitsthreads in einer Multithread-Umgebung konzipiert. Serverzeitgeber können sich zwischen Threads bewegen, um das ausgelöste abgelaufene Ereignis zu behandeln, was zu einer höheren Genauigkeit als Windows-Zeitgebern führt, wenn das Ereignis rechtzeitig ausgelöst wird.

1
Marc Gravell

Hier finden Sie ein Beispiel für die Verwendung von Timer in Windows Service .

1
Paweł Smejda

vollständig getestete Lösung ...

 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; }
        }
    }
0
Nuri YILMAZ