Ambos System.Timers.Timer
e System.Threading.Timer
funcionarão para serviços.
Os temporizadores que você deseja evitar são System.Web.UI.Timer
e System.Windows.Forms.Timer
, que são respectivamente para aplicativos ASP e WinForms. O uso deles fará com que o serviço carregue um assembly adicional que não é realmente necessário para o tipo de aplicativo que você está construindo.
Use System.Timers.Timer
como o exemplo a seguir (também, certifique-se de usar uma variável de nível de classe para evitar a coleta de lixo, conforme declarado na resposta 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
...
*/
Se preferir System.Threading.Timer
, você pode usar o seguinte:
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();
}
}
}
Ambos os exemplos vêm das páginas do MSDN.
Não use um serviço para isso. Crie um aplicativo normal e crie uma tarefa agendada para executá-lo.
Esta é a melhor prática comumente aceita. Jon Galloway concorda comigo. Ou talvez seja o contrário. De qualquer forma, o fato é que não é uma prática recomendada criar um serviço do Windows para executar uma tarefa intermitente executada por um cronômetro.
fonte
Qualquer um deve funcionar bem. Na verdade, System.Threading.Timer usa System.Timers.Timer internamente.
Dito isso, é fácil usar mal o System.Timers.Timer. Se você não armazenar o objeto Timer em uma variável em algum lugar, ele poderá ser coletado como lixo. Se isso acontecer, o cronômetro não disparará mais. Chame o método Dispose para interromper o cronômetro ou use a classe System.Threading.Timer, que é um wrapper ligeiramente melhor.
Que problemas você viu até agora?
fonte
System.Timers.Timer
porque ele não lida com as exceções lançadas nele.Concordo com o comentário anterior que pode ser melhor considerar uma abordagem diferente. Minha sugestão seria escrever um aplicativo de console e usar o agendador do Windows:
Isso vai:
fonte
Como já foi dito
System.Threading.Timer
eSystem.Timers.Timer
funcionará. A grande diferença entre os dois é queSystem.Threading.Timer
existe um envoltório ao redor do outro.Isso me deu grandes problemas no passado, então eu sempre usaria 'System.Threading.Timer' e ainda lidaria muito bem com suas exceções.
fonte
Sei que este tópico é um pouco antigo, mas foi útil para um cenário específico que eu tive e achei que vale a pena observar que há outro motivo pelo qual
System.Threading.Timer
pode ser uma boa abordagem. Quando você tem que executar periodicamente um trabalho que pode levar muito tempo e você deseja garantir que todo o período de espera seja usado entre os trabalhos ou se você não quiser que o trabalho seja executado novamente antes que o trabalho anterior termine no caso em que o trabalho leva mais tempo do que o período do cronômetro. Você pode usar o seguinte:fonte