Cómo se agrega un temporizador a una aplicación de consola C #

Simplemente esto: ¿cómo se agrega un temporizador a una aplicación de consola C #? Sería genial si pudiera proporcionar algunos ejemplos de encoding.

Eso es muy bueno, sin embargo, para simular que pase algo de tiempo, necesitamos ejecutar un comando que lleva algo de tiempo y eso está muy claro en el segundo ejemplo.

Sin embargo, el estilo de utilizar un bucle for para realizar algunas funciones siempre requiere una gran cantidad de recursos del dispositivo y, en su lugar, podemos usar el Garbage Collector para hacer algo así.

Podemos ver esta modificación en el código del mismo libro 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 la clase System.Threading.Timer.

System.Windows.Forms.Timer está diseñado principalmente para su uso en un único hilo, generalmente el subproceso de interfaz de usuario de Windows Forms.

También hay una clase System.Timers agregada desde el principio en el desarrollo del framework .NET. Sin embargo, en general, se recomienda utilizar la clase System.Threading.Timer en su lugar, ya que esto es solo una envoltura alrededor de System.Threading.Timer de todos modos.

También se recomienda utilizar siempre un sistema estático (compartido en VB.NET) System.Threading.Timer si está desarrollando un servicio de Windows y necesita un temporizador para ejecutarse periódicamente. Esto evitará la posible recolección prematura de basura de su objeto de temporizador.

Aquí hay un ejemplo de un temporizador en una aplicación de consola:

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

Del libro CLR Via C # de Jeff Richter. Por cierto este libro describe la razón de ser de los 3 tipos de temporizadores en el Capítulo 23, altamente recomendado.

Aquí está el código para crear un simple ticker de un 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); } } } 

Y aquí está el resultado 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 

EDITAR: Nunca es una buena idea agregar bucles duros en el código ya que consumen ciclos de CPU sin ganancia. En este caso, ese bucle se agregó solo para detener el cierre de la aplicación, lo que permite observar las acciones del hilo. Pero en aras de la corrección y de reducir el uso de la CPU, se agregó una llamada de suspensión simple a ese bucle.

Vamos a divertirnos un poco

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

O usando Rx, corto y dulce:

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

También puede usar sus propios mecanismos de sincronización si desea un poco más de control, pero posiblemente menos precisión y más código / complejidad, pero aún así le recomendaría un temporizador. Sin embargo, use esto si necesita tener control sobre el hilo de tiempo real:

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

sería su hilo de temporización (modifíquelo para detenerlo cuando lo requiera, y en el intervalo de tiempo que desee).

y para usar / comenzar puedes hacer:

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

La callback es su método sin parámetros void que desea llamar en cada intervalo. Por ejemplo:

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

También puede crear uno propio (si no está satisfecho con las opciones disponibles).

Crear su propia implementación de Timer es bastante básico.

Este es un ejemplo para una aplicación que necesitaba acceso a objetos COM en el mismo hilo que el rest de mi 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(); } } 

Puede agregar eventos de la siguiente manera:

 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 asegurarse de que el temporizador funcione, debe crear un bucle infinito de la siguiente manera:

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