Les deux System.Timers.Timer
et System.Threading.Timer
travailleront pour les services.
Les minuteries que vous souhaitez éviter sont System.Web.UI.Timer
et System.Windows.Forms.Timer
, qui sont respectivement pour les applications ASP et WinForms. Leur utilisation entraînera le chargement d'un assemblage supplémentaire par le service qui n'est pas vraiment nécessaire pour le type d'application que vous créez.
Utilisez System.Timers.Timer
comme l'exemple suivant (assurez-vous également d'utiliser une variable de niveau de classe pour empêcher le garbage collection, comme indiqué dans la réponse de Tim Robinson):
using System;
using System.Timers;
public class Timer1
{
private static System.Timers.Timer aTimer;
public static void Main()
{
// Normally, the timer is declared at the class level,
// so that it stays in scope as long as it is needed.
// If the timer is declared in a long-running method,
// KeepAlive must be used to prevent the JIT compiler
// from allowing aggressive garbage collection to occur
// before the method ends. (See end of method.)
//System.Timers.Timer aTimer;
// Create a timer with a ten second interval.
aTimer = new System.Timers.Timer(10000);
// Hook up the Elapsed event for the timer.
aTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
// Set the Interval to 2 seconds (2000 milliseconds).
aTimer.Interval = 2000;
aTimer.Enabled = true;
Console.WriteLine("Press the Enter key to exit the program.");
Console.ReadLine();
// If the timer is declared in a long-running method, use
// KeepAlive to prevent garbage collection from occurring
// before the method ends.
//GC.KeepAlive(aTimer);
}
// Specify what you want to happen when the Elapsed event is
// raised.
private static void OnTimedEvent(object source, ElapsedEventArgs e)
{
Console.WriteLine("The Elapsed event was raised at {0}", e.SignalTime);
}
}
/* This code example produces output similar to the following:
Press the Enter key to exit the program.
The Elapsed event was raised at 5/20/2007 8:42:27 PM
The Elapsed event was raised at 5/20/2007 8:42:29 PM
The Elapsed event was raised at 5/20/2007 8:42:31 PM
...
*/
Si vous le souhaitez System.Threading.Timer
, vous pouvez utiliser comme suit:
using System;
using System.Threading;
class TimerExample
{
static void Main()
{
AutoResetEvent autoEvent = new AutoResetEvent(false);
StatusChecker statusChecker = new StatusChecker(10);
// Create the delegate that invokes methods for the timer.
TimerCallback timerDelegate =
new TimerCallback(statusChecker.CheckStatus);
// Create a timer that signals the delegate to invoke
// CheckStatus after one second, and every 1/4 second
// thereafter.
Console.WriteLine("{0} Creating timer.\n",
DateTime.Now.ToString("h:mm:ss.fff"));
Timer stateTimer =
new Timer(timerDelegate, autoEvent, 1000, 250);
// When autoEvent signals, change the period to every
// 1/2 second.
autoEvent.WaitOne(5000, false);
stateTimer.Change(0, 500);
Console.WriteLine("\nChanging period.\n");
// When autoEvent signals the second time, dispose of
// the timer.
autoEvent.WaitOne(5000, false);
stateTimer.Dispose();
Console.WriteLine("\nDestroying timer.");
}
}
class StatusChecker
{
int invokeCount, maxCount;
public StatusChecker(int count)
{
invokeCount = 0;
maxCount = count;
}
// This method is called by the timer delegate.
public void CheckStatus(Object stateInfo)
{
AutoResetEvent autoEvent = (AutoResetEvent)stateInfo;
Console.WriteLine("{0} Checking status {1,2}.",
DateTime.Now.ToString("h:mm:ss.fff"),
(++invokeCount).ToString());
if(invokeCount == maxCount)
{
// Reset the counter and signal Main.
invokeCount = 0;
autoEvent.Set();
}
}
}
Les deux exemples proviennent des pages MSDN.
N'utilisez pas de service pour cela. Créez une application normale et créez une tâche planifiée pour l'exécuter.
Il s'agit de la meilleure pratique courante. Jon Galloway est d'accord avec moi. Ou peut-être que c'est l'inverse. Quoi qu'il en soit, le fait est qu'il n'est pas recommandé de créer un service Windows pour effectuer une tâche intermittente exécutée sur un minuteur.
la source
L'un ou l'autre devrait fonctionner correctement. En fait, System.Threading.Timer utilise System.Timers.Timer en interne.
Cela dit, il est facile de mal utiliser System.Timers.Timer. Si vous ne stockez pas l'objet Timer quelque part dans une variable, il est susceptible d'être récupéré. Si cela se produit, votre minuterie ne se déclenchera plus. Appelez la méthode Dispose pour arrêter le minuteur ou utilisez la classe System.Threading.Timer, qui est un wrapper légèrement plus agréable.
Quels problèmes avez-vous vus jusqu'à présent?
la source
System.Timers.Timer
parce qu'il ne gérera pas les exceptions qui lui sont lancées.Je suis d'accord avec le commentaire précédent qu'il serait peut-être préférable d'envisager une approche différente. Ma suggestion serait d'écrire une application console et d'utiliser le planificateur Windows:
Cette volonté:
la source
Comme déjà indiqué à la fois
System.Threading.Timer
etSystem.Timers.Timer
fonctionnera. La grande différence entre les deux est qu'ilSystem.Threading.Timer
y a un wrapper autour de l'autre.Cela m'a posé de gros problèmes dans le passé, donc j'utilisais toujours 'System.Threading.Timer' et je gérais toujours très bien vos exceptions.
la source
Je sais que ce fil est un peu vieux, mais il m'a été utile pour un scénario spécifique que j'avais et j'ai pensé qu'il valait la peine de noter qu'il y a une autre raison pour laquelle
System.Threading.Timer
une bonne approche pourrait être. Lorsque vous devez exécuter périodiquement un Job qui peut prendre du temps et que vous voulez vous assurer que toute la période d'attente est utilisée entre les jobs ou si vous ne voulez pas que le job soit à nouveau exécuté avant la fin du job précédent dans le cas où le travail prend plus de temps que la période du minuteur. Vous pouvez utiliser les éléments suivants:la source