Programing

C # 콘솔 응용 프로그램에 타이머를 추가하는 방법

crosscheck 2020. 7. 6. 07:54
반응형

C # 콘솔 응용 프로그램에 타이머를 추가하는 방법


그냥-C # 콘솔 응용 프로그램에 타이머를 어떻게 추가합니까? 예제 코딩을 제공 할 수 있다면 좋을 것입니다.


시간이 지남에 따라 시뮬레이션하려면 시간이 걸리는 명령을 실행해야하며 두 번째 예에서는 매우 분명합니다.

그러나 for 루프를 사용하여 일부 기능을 수행하는 스타일에는 많은 장치 리소스가 필요하지만 가비지 수집기를 사용하여 이와 같은 작업을 수행 할 수 있습니다.

동일한 책 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 <Enter>
      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();
   }
}

System.Threading.Timer 클래스를 사용하십시오.

System.Windows.Forms.Timer는 주로 단일 스레드, 일반적으로 Windows Forms UI 스레드에서 사용하도록 설계되었습니다.

.NET 프레임 워크 개발 초기에 System.Timers 클래스가 추가되었습니다. 그러나 System.Threading.Timer 클래스는 System.Threading.Timer 주위의 래퍼이므로 일반적으로 대신 System.Threading.Timer 클래스를 사용하는 것이 좋습니다.

Windows 서비스를 개발 중이고 주기적으로 타이머를 실행해야하는 경우 항상 정적 (VB.NET에서 공유) System.Threading.Timer를 사용하는 것이 좋습니다. 이것은 타이머 객체의 조기 가비지 수집을 피할 것입니다.

다음은 콘솔 응용 프로그램의 타이머 예입니다.

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

Jeff Richter의 CLR Via C # 책에서 . 그런데이 책은 23 장의 3 가지 유형의 타이머에 대한 이론적 근거를 적극 권장합니다.


간단한 1 초 타이머 틱을 만드는 코드는 다음과 같습니다.

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

결과는 다음과 같습니다.

    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

편집 : 하드 스핀 루프를 이득없이 CPU 사이클을 소비하므로 코드에 하드 스핀 루프를 추가하는 것은 결코 좋은 생각이 아닙니다. 이 경우 응용 프로그램이 닫히지 않도록 루프가 추가되어 스레드의 동작을 관찰 할 수 있습니다. 그러나 정확성을 위해 그리고 CPU 사용을 줄이기 위해 간단한 Sleep 호출이 해당 루프에 추가되었습니다.


조금 재미있게 보내자

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("                  DEFUSE 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("         B O O O O O M M M M M ! ! ! !");
                Console.WriteLine("");
                Console.WriteLine("               G A M E  O V E R");
                Console.WriteLine("==============================================");

                timer.Close();
                timer.Dispose();
            }

            GC.Collect();
        }
    }
}

또는 짧고 달콤한 Rx를 사용하십시오.

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

for (; ; ) { }
}

약간의 제어를 원하지만 정확도와 코드 / 복잡성을 낮추려면 자체 타이밍 메커니즘을 사용할 수도 있지만 타이머를 권장합니다. 실제 타이밍 스레드를 제어해야하는 경우이를 사용하십시오.

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

타이밍 스레드가 될 것입니다 (요청 할 때, 원하는 시간 간격으로 중지하도록 수정하십시오).

사용 / 시작하려면 다음을 수행하십시오.

Thread t = new Thread(new ParameterizedThreadStart(ThreadLoop));

t.Start((Action)CallBack);

Callback is your void parameterless method that you want called at each interval. For example:

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

You can also create your own (if unhappy with the options available).

Creating your own Timer implementation is pretty basic stuff.

This is an example for an application that needed COM object access on the same thread as the rest of my codebase.

/// <summary>
/// Internal timer for window.setTimeout() and window.setInterval().
/// This is to ensure that async calls always run on the same thread.
/// </summary>
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();
    }

}

You can add events as follows:

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

To make sure the timer works you need to create an endless loop as follows:

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

참고URL : https://stackoverflow.com/questions/186084/how-do-you-add-a-timer-to-a-c-sharp-console-application

반응형