2011-02-02 4 views
2

나는 Windows 응용 프로그램이 있습니다. 자동 저장 기능을 백그라운드 프로세스로 구현했습니다.특정 시간 간격 후에 작업을 수행하는 가장 좋은 방법은 무엇입니까?

샘플 코드는 다음과 같습니다 :

While(1) 
{ 
    Thread.Sleep(60000) // 1 minute sleep 
    DoAutoSaveAllControls(); 
} 

내가이 나쁜 기능이라고 생각합니다. 내가 틀렸다면 나를 바로 잡아라. 그러나 성능을 향상시키고 Sleep을 수행하지 않고 특정 시간 간격 후에이 작업을 수행하려고합니다. 또한 백그라운드 프로세스에서이 작업을 수행하는 것이 좋습니까?

+0

또한이 관련 질문 참조 : http://stackoverflow.com/questions/391621/compare-using-thread-sleep-and-timer-for ([시각 실행 Thread.sleep를 타이머를 사용하여 비교] -delayed-execution) –

답변

4

훨씬 더 나은 방법은 타이머를 사용하는 것입니다. 이 우수한 기사에서 .NET 프레임 워크의 다양한 다른 타이머에 대해 찾을 수 있습니다 : 당신은 윈폼을 사용하는

http://msdn.microsoft.com/en-us/magazine/cc164015.aspx

, 그래서 System.Windows.Forms.Timer 당신을 위해 잘 될 것입니다. 예를 들어

:

System.Windows.Forms.Timer tmrWindowsFormsTimer = new System.Windows.Forms.Timer(); 
tmrWindowsFormsTimer.Interval = TimeSpan.FromMinutes(1); 
tmrWindowsFormsTimer.Tick += new EventHandler(tmrWindowsFormsTimer_Tick); 
tmrWindowsFormsTimer.Start(); 


private void tmrWindowsFormsTimer_Tick(object sender, System.EventArgs e) { 
    tmrWindowsFormsTimer.Stop(); 
    DoAutoSaveAllControls(); 
} 

이것은 첫 번째 틱 후 효과적으로 화재 번 타이머를 타이머를 중지합니다.

0

Thread.Sleep 성능에 전혀 영향을 미치지 않습니다. 나에게 완벽하게 좋지만 응용 프로그램이 아마도 UI 스레드에서 문서를 수정하고 있기 때문에 동시 수정을 피하기 위해 저장을 sincronize해야 할 것이다. 이러한 이유 때문에 BackGroundWorker 대신 Timer를 사용하는 것이 더 나을 것입니다.

+0

'while + sleep' 솔루션은 스레드를 항상 점유함으로써 성능을 약간 손상시킵니다. 클라이언트에서는 OK, 서버 앱에서는 수용 할 수 없습니다. –

+0

'Thread.Sleep'은 여러 가지 이유로 잘못된 해결책입니다. [흥미로운 관련 읽기] (http://msmvps.com/blogs/peterritchie/archive/2007/04/26/thread-sleep-is-a-sign-of-a-poorly-designed-program.aspx). –

+0

슬리핑 스레드는 CPU를 소비하지 않습니다.권장할만한 아이디어가 아니지만 성능 누수가 잘못되었다고 말하는 것은 –

0

당신 말이 맞아요, 정말 스레드의 좋은 사용 아니에요. Timer 클래스를 살펴보십시오.

0

나는 변경 사항이 이미 발생했는지 알고있는 호출 코드에서 기능을 저장해야한다고 생각합니다. 따라서 저장 스레드는 호출 스레드가 저장을 위해 몇 가지 변경을 수행했음을 알 수 있습니다.

이것은이 질문에 대한 답변이 아니며 단지 권장 사항 일 수 있습니다. 따라서 타이머 내부에서 Save를 호출하는 경우 변경 사항이 발생했는지 먼저 확인해야합니다. 그렇게하기 위해서는 쓰레드와 저장 쓰레드에 공통적 인 몇 가지 추가 변수가 필요합니다. 작업 스레드가 무언가를 변경하면 var이 true로 트리거됩니다. 저장시 var가 true이면 저장이 필요합니다. 저장 후 common var를 false로 변경합니다.

+1

이것은 아마도 내가 본 중에 가장 모호한 대답 일 것입니다. 그래서, 어떤 일을하는 일종의 호출 코드를 막기 위해 뭔가를해야합니까? –

+0

네, 동의합니다 ... 가끔은 뭔가를 말하고 조금 더 서둘러야 할 때가 있습니다. –

0

당신은 일정한 시간 간격 후 프로세스를 시작 System.Timers.Timer를 사용할 수 well.It 더 자연 보이는 당신은이에 대한 반응성 Extenssions를 사용할 수있는 샘플 조각을

aTimer = new System.Timers.Timer(10000); 

    // Hook up the Elapsed event for the timer. 
    aTimer.Elapsed += new ElapsedEventHandler(YourHandlerMethod); 

    // Set the Interval to 2 seconds (2000 milliseconds). 
    aTimer.Interval = 2000; 
    aTimer.Enabled = true; 
2

을 확인하고는 관찰 가능한 결합 할 수 있습니다.

var observable = Observable.Timer(
        TimeSpan.FromMinutes(1), 
        TimeSpan.FromMinutes(1)).Timestamp(); 

    using (observable.Subscribe())) 
    { 
     DoAutoSave(); 
    } 
관련 문제