2016-11-21 3 views
0

기능을 Elapsed로 설정하여 System.Timers.Timer을 사용하고 있습니다. 'aTimer.Elapsed + = OnTimedEvent`는 규칙적인 시간에 주기적으로 실행되도록 설정됩니다. 5 초마다 발생한다고 가정 해 봅시다.타이머 (Elapsed 함수를 여러 번 호출)

어떤 이유로 인해 OnTimedEvent 처리가 마지막으로 보다 많고 초가 지나면 어떻게됩니까?

설명서에 따르면 * 이벤트가 다른 ThreadPool 스레드에서 다시 발생할 수 있습니다. 이 상황에서 이벤트 핸들러는 재진입 성이 있어야합니다. *

어떻게 든 이론적 인 용어로 이해할 수 있지만, 누군가이 설명을 나에게 쉽고 실용적인 용어로 설명 할 수 있습니까?


내 onTimedEvent에서 도움이된다면 NetworkStream에서 읽으려고합니다.

+0

직접 해보십시오. 'OnTimedEvent' 안에'Thread.Sleep (7000) '척하십시오. – Rob

+0

[AutoReset 속성] (https://msdn.microsoft.com/en-us/library/system.timers.timer.autoreset (v = vs.110) .aspx)을 * false *로 설정하십시오. 기사의 예제 코드가 약간 깨져서 Elapsed 이벤트 핸들러의 끝에서 Start()를 호출하여 타이머가 다시 진드기가되게합니다. 그리고 이벤트 처리기에서 try/catch/finally를 많이 선호합니다. –

답변

1

간단히 말해 OnTimedEvent는 동시에 진행되는 여러 스레드를 지원할 수 있어야합니다. 왜? 메소드를 실행하는 동안 타이머를 중지하지 않으면 5 초 후에 다시 실행됩니다. 하지만 이번에는 첫 번째 스레드가 첫 번째 호출을 실행 중일 때 다른 스레드에서 실행됩니다. 따라서 두 번째 스레드가 메서드에 들어갑니다. 이 시점에서 OnTimedEvent가 스레드 안전하지 않으면 나쁜 일이 발생할 수 있습니다.

여러 스레드를 지원하는 것에 대해 Google에 자세한 정보를 제공 할 수 있으며 충분한 정보를 찾을 수 있어야합니다.

대부분의 경우 사람들은 메서드가 실행되는 동안 타이머를 중지 한 다음 메서드가 끝나면 다시 시작합니다. 그러나 이것은 당신의 요구 사항과 당신이하는 일에 달려 있습니다. 여기

비 재진입 방법의 예 : T1은 그것의 실행에있어서 내부와 합에 1을 추가하는 경우

static int sum = 0; 

int increment(int i) { 
    sum += i; 
    return sum; 
} 

이 때문에 재진입하지 않고, 합계 경우 1.해질 것이다 그것 이 시점에서 실행 제어가 취해지고 T2에 주어 졌음을 의미하며, T2가 오면 sum의 값은 0이 아니지만 1이됩니다. T2는 sum에 1을 더하고 2를 반환합니다. T1이 돌아 오면 즉, 그것은 이미 1을 반환 할 것입니다. 따라서 2 개의 스레드가 다른 결과를 남겼습니다 : 1의 T1, 2의 T2. 따라서이 메서드는 재진입이 아닙니다.

int increment(int sum, int i) 
{ 
    return sum + i; 
} 

이제 각 스레드가 모든 변수 때문에 메소드 실행의 중간에 떠날 경우에도 같은 대답으로 돌아갑니다

가 있습니다 :

가 다시 참가자를 만들기 위해, 우리는 단순히 이렇게 스택에 의해 공유되지 않고 스레드에 의해 공유되지 않습니다 (각 스레드는 변수의 자체 사본을가집니다).

This 당신이 더 읽고 싶다면 SO 대답은 훌륭한 정보와 설명이 있습니다.

관련 문제