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?
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
Elapsed
einen Handler hinzu (oder übergeben Sie ihm einen Rückruf bei der Erstellung).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.
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);
}
}
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.
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.
Hier finden Sie ein Beispiel für die Verwendung von Timer in Windows Service .
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; }
}
}