2010-06-16 3 views
7

자정 때마다 코드를 트리거하는 WinForm 용 백그라운드 작업자를 만들고 싶습니다.자정 때 배경 근로자 확인?

나는 그것을하는 방법에 대한 아이디어가 있지만, 그것을하는 것이 최선의 방법은 아니라고 확신합니다.

while(1==1) 
{ 
//if Datetime.Now == midnight, execute code 
//sleep(1second) 
} 
+0

빠른 참고 사항 ... "끝내지 않는"루프 (물론 '중단'이있을 수 있음)를 만들고 싶다면'while (true) {}'을 할 수 있습니다. '1 == 1'은 어쨌든'true'로 평가됩니다. –

+0

그게 표준인가요? 나는 1 == 1을 사용하는 것에 대해 확신하지 못했습니다. – sooprise

답변

21

System.Timers.Timer을 사용하고 응용 프로그램 시작시에만 DateTime.NowDateTime.Today.AddDays(0)의 차이를 계산하십시오. 그런 다음 해당 금액의 간격을 설정하십시오.

public static class DayChangedNotifier 
{ 
    private static Timer timer; 

    static DayChangedNotifier() 
    { 
     timer = new Timer(GetSleepTime()); 
     timer.Elapsed += (o, e) => 
      { 
       OnDayChanged(DateTime.Now.DayOfWeek); 
       timer.Interval = this.GetSleepTime(); 
      }; 
     timer.Start(); 

     SystemEvents.TimeChanged += new EventHandler(SystemEvents_TimeChanged); 
    } 

    private static void SystemEvents_TimeChanged(object sender, EventArgs e) 
    { 
     timer.Interval = GetSleepTime(); 
    } 

    private static double GetSleepTime() 
    { 
     var midnightTonight = DateTime.Today.AddDays(1); 
     var differenceInMilliseconds = (midnightTonight - DateTime.Now).TotalMilliseconds; 
     return differenceInMilliseconds; 
    } 

    private static void OnDayChanged(DayOfWeek day) 
    { 
     var handler = DayChanged; 
     if (handler != null) 
     { 
      handler(null, new DayChangedEventArgs(day)); 
     } 
    } 

    public static event EventHandler<DayChangedEventArgs> DayChanged; 
} 

AND :

public class DayChangedEventArgs : EventArgs 
{ 
    public DayChangedEventArgs(DayOfWeek day) 
    { 
     this.DayOfWeek = day; 
    } 

    public DayOfWeek DayOfWeek { get; private set; } 
} 

Useage : DayChangedNotified.DayChanged += ....

+0

그래서 배경 작업자가 필요하지 않습니까? – sooprise

+0

@ Sou : Nope. Timer가 차단되지 않습니다 (나머지 코드는 중지됩니다 - http://en.wikipedia.org/wiki/Blocking_%28computing%29). 간격이 끝나면 Tick 이벤트를 호출합니다. 그 시점에서 원하는 경우 타이머를 중지하고 다음 간격을 계산 한 다음 다시 시작할 수 있습니다. –

+0

아니요, System.Timers가 다른 스레드에서 실행되므로 조심해야 할 것은 타이머의 이벤트 처리기에서 Invoke를 호출하는 것입니다. – BFree

7

대신 타이머를 사용하고 타이머 틱 간격을 Now()와 자정 사이의 시간으로 설정할 수 있습니다.

0

Quartz을 사용하면 일정을 예약 할 수 있습니다. 어쩌면이 시나리오에서 모기를 죽일 대포와 같을 것입니다. 그러나 이것은 내가 아는 스케줄링 작업 프레임 워크이고 우수합니다.

0

사용하지 마십시오 폴링

는 사실은 최근 단지 같은 것을했다. 대신 타이머 작업을 설정하고 자정에 시작하도록 설정하고 처리 할 이벤트를 추가하십시오. Microsoft는 타이밍을 처리하기 위해 Windows 서비스를 추가하여 년 전 이러한 유형의 문제를 해결할 때 폴링 솔루션은 최대로 선정 된 이유

TimeSpan timeBetween = DateTime.Today.AddDays(1) - DateTime.Now; 

System.Timers.Timer t = new System.Timers.Timer(); 
t.Elapsed += new System.Timers.ElapsedEventHandler(t_Elapsed); 
t.Interval = 1000 * timeBetween.Seconds; 
t.Start(); 
+0

그래서 t_Elapsed가 트리거 된 후에 timeBetween이 다시 계산됩니까? – sooprise

+0

t_Elapsed 메소드에서 간격을 다시 계산합니다. – cortijon

0

나는 아무 생각이 없습니다. 그냥 exe를 실행하는 예약 된 작업을 만듭니다. 여분의 오버 헤드가 없습니다.

0

왜 자정에 WinForm이 필요한지 조금 혼란 스럽습니까? 필요한 것은 일종의 정렬 프로세스입니다. Windows 스케줄러를 사용하여 자정에 실행하십시오. (XP에서는,하지만 윈도우 서버는 비슷해야한다고 생각합니다.) 제어판 -> 예약 된 작업 -> 예약 된 작업 추가 -> 마법사를 작성하십시오. 많은 코딩을 저장하십시오.

관련 문제