Como você adiciona um timer a um aplicativo de console C #

Apenas isso – Como você adiciona um timer para um aplicativo de console C #? Seria ótimo se você pudesse fornecer algum exemplo de codificação.

    Isso é muito bom, no entanto, a fim de simular algum tempo que passa precisamos executar um comando que leva algum tempo e isso é muito claro no segundo exemplo.

    No entanto, o estilo de usar um loop for para fazer algumas funcionalidades sempre exige muitos resources do dispositivo e, em vez disso, podemos usar o Garbage Collector para fazer algo assim.

    Podemos ver essa modificação no código do mesmo livro CLR Via C # Third Ed.

    using System; using System.Threading; public static class Program { public static void Main() { // Create a Timer object that knows to call our TimerCallback // method once every 2000 milliseconds. Timer t = new Timer(TimerCallback, null, 0, 2000); // Wait for the user to hit  Console.ReadLine(); } private static void TimerCallback(Object o) { // Display the date/time when this method got called. Console.WriteLine("In TimerCallback: " + DateTime.Now); // Force a garbage collection to occur for this demo. GC.Collect(); } } 

    Use a class System.Threading.Timer.

    System.Windows.Forms.Timer é projetado principalmente para uso em um único segmento geralmente o segmento de interface do usuário do Windows Forms.

    Há também uma class System.Timers adicionada no início do desenvolvimento do .NET framework. No entanto, geralmente é recomendável usar a class System.Threading.Timer, já que isso é apenas um wrapper em torno de System.Threading.Timer.

    Também é recomendável usar sempre um System.Threading.Timer estático (compartilhado em VB.NET) se você estiver desenvolvendo um Serviço do Windows e precisar de um timer para ser executado periodicamente. Isso evitará a garbage collection possivelmente prematura de seu object de timer.

    Aqui está um exemplo de um timer em um aplicativo de console:

     using System; using System.Threading; public static class Program { public static void Main() { Console.WriteLine("Main thread: starting a timer"); Timer t = new Timer(ComputeBoundOp, 5, 0, 2000); Console.WriteLine("Main thread: Doing other work here..."); Thread.Sleep(10000); // Simulating other work (10 seconds) t.Dispose(); // Cancel the timer now } // This method's signature must match the TimerCallback delegate private static void ComputeBoundOp(Object state) { // This method is executed by a thread pool thread Console.WriteLine("In ComputeBoundOp: state={0}", state); Thread.Sleep(1000); // Simulates other work (1 second) // When this method returns, the thread goes back // to the pool and waits for another task } } 

    Do livro CLR Via C # de Jeff Richter. A propósito, este livro descreve a lógica por trás dos 3 tipos de timeres no Capítulo 23, altamente recomendados.

    Aqui está o código para criar um simples timer de um segundo:

      using System; using System.Threading; class TimerExample { static public void Tick(Object stateInfo) { Console.WriteLine("Tick: {0}", DateTime.Now.ToString("h:mm:ss")); } static void Main() { TimerCallback callback = new TimerCallback(Tick); Console.WriteLine("Creating timer: {0}\n", DateTime.Now.ToString("h:mm:ss")); // create a one second timer tick Timer stateTimer = new Timer(callback, null, 0, 1000); // loop here forever for (; ; ) { // add a sleep for 100 mSec to reduce CPU usage Thread.Sleep(100); } } } 

    E aqui está a saída resultante:

      c:\temp>timer.exe Creating timer: 5:22:40 Tick: 5:22:40 Tick: 5:22:41 Tick: 5:22:42 Tick: 5:22:43 Tick: 5:22:44 Tick: 5:22:45 Tick: 5:22:46 Tick: 5:22:47 

    EDIT: Nunca é uma boa idéia adicionar hard spin loops em código como eles consomem ciclos de CPU para nenhum ganho. Nesse caso, esse loop foi adicionado apenas para impedir o fechamento do aplicativo, permitindo que as ações do encadeamento sejam observadas. Mas, por questão de correção e para reduzir o uso da CPU, uma simples chamada Sleep foi adicionada a esse loop.

    Vamos ter um pouco de diversão

     using System; using System.Timers; namespace TimerExample { class Program { static Timer timer = new Timer(1000); static int i = 10; static void Main(string[] args) { timer.Elapsed+=timer_Elapsed; timer.Start(); Console.Read(); } private static void timer_Elapsed(object sender, ElapsedEventArgs e) { i--; Console.Clear(); Console.WriteLine("================================================="); Console.WriteLine(" DIFFUSE THE BOMB"); Console.WriteLine(""); Console.WriteLine(" Time Remaining: " + i.ToString()); Console.WriteLine(""); Console.WriteLine("================================================="); if (i == 0) { Console.Clear(); Console.WriteLine(""); Console.WriteLine("=============================================="); Console.WriteLine(" BOOOOOMMMMM ! ! ! !"); Console.WriteLine(""); Console.WriteLine(" GAMEOVER"); Console.WriteLine("=============================================="); timer.Close(); timer.Dispose(); } GC.Collect(); } } } 

    Ou usando Rx, curto e doce:

     static void Main() { Observable.Interval(TimeSpan.FromSeconds(10)).Subscribe(t => Console.WriteLine("I am called... {0}", t)); for (; ; ) { } } 

    Você também pode usar seus próprios mecanismos de temporização se quiser um pouco mais de controle, mas possivelmente menos precisão e mais código / complexidade, mas eu ainda recomendaria um timer. Use isso, porém, se você precisa ter controle sobre o segmento de tempo real:

     private void ThreadLoop(object callback) { while(true) { ((Delegate) callback).DynamicInvoke(null); Thread.Sleep(5000); } } 

    seria o seu segmento de tempo (modifique isso para parar quando necessário e em qualquer intervalo de tempo desejado).

    e para usar / start você pode fazer:

     Thread t = new Thread(new ParameterizedThreadStart(ThreadLoop)); t.Start((Action)CallBack); 

    Callback é o seu método sem parâmetros que você deseja chamar em cada intervalo. Por exemplo:

     private void CallBack() { //Do Something. } 

    Você também pode criar o seu próprio (se não estiver satisfeito com as opções disponíveis).

    Criar sua própria implementação de Timer é uma coisa bastante básica.

    Este é um exemplo para um aplicativo que precisava de access a objects COM no mesmo thread que o restante de minha base de código.

     ///  /// Internal timer for window.setTimeout() and window.setInterval(). /// This is to ensure that async calls always run on the same thread. ///  public class Timer : IDisposable { public void Tick() { if (Enabled && Environment.TickCount >= nextTick) { Callback.Invoke(this, null); nextTick = Environment.TickCount + Interval; } } private int nextTick = 0; public void Start() { this.Enabled = true; Interval = interval; } public void Stop() { this.Enabled = false; } public event EventHandler Callback; public bool Enabled = false; private int interval = 1000; public int Interval { get { return interval; } set { interval = value; nextTick = Environment.TickCount + interval; } } public void Dispose() { this.Callback = null; this.Stop(); } } 

    Você pode adicionar events da seguinte maneira:

     Timer timer = new Timer(); timer.Callback += delegate { if (once) { timer.Enabled = false; } Callback.execute(callbackId, args); }; timer.Enabled = true; timer.Interval = ms; timer.Start(); Window.timers.Add(Environment.TickCount, timer); 

    Para garantir que o timer funcione, você precisa criar um loop infinito da seguinte maneira:

     while (true) { // Create a new list in case a new timer // is added/removed during a callback. foreach (Timer timer in new List(timers.Values)) { timer.Tick(); } }