2011-10-18 3 views
4

Silverlight 응용 프로그램에서는 500ms마다 실행해야하는 코드 블록이 있습니다. DispatcherTimer를 사용하여이 작업을 수행 할 계획입니다 (아래 코드 참조).DispatchTimer - 이전 틱이 여전히 실행 중일 때 틱 이벤트가 트리거되지 않도록 방지합니다.

DispatcherTimer dt = new DispatcherTimer(); 
dt.Interval = new TimeSpan(0, 0, 0, 0, 500); // 500 Milliseconds 
dt.Tick += new EventHandler(dt_Tick); 
dt.Start(); 

그러나 코드 블록이 500ms보다 오래 걸릴 수도 있습니다 (코드 블록이 일부 웹 서비스 호출을 수행함). 현재 통화가 진행중인 경우 DispatcherTimer가 다른 이벤트를 트리거하지 않도록하려면 어떻게해야합니까? 옵션에는 무엇이 있으며 가장 좋은 방법은 무엇입니까? 잠금 장치 사용?

답변

1

너무 오래 걸리면 진드기를 건너 뛰고 그렇지 않으면 자물쇠 때문에 거대한 대기열이 생깁니다. 그래서 이벤트 핸들러에서

말 : DispatchTimer이 작업을 수행 할 수있는 영리한 방법이 있지만 내가이 상황에서하는 것은 해고하지 않는 타이머를 얻으려고하지 않을 경우

if(!busy) { 
    busy = true; 

    // some code which could take longer than 500 ms 

    busy = false; 
} 
1

나도 몰라 이벤트를 가져 오지 만 이전 실행을 완료하지 않은 경우 이벤트를 수행하지 않습니다.

잠금은 이벤트 처리기 시작 부분에 잠금을 설정하여 수행 할 수 있습니다. 자물쇠를 사용할 수 없다면 자물쇠가 작동하면 작업을 종료하고 잠긴 후에는 자물쇠를 해제하십시오.

원하는 방법은 Monitor.TryEnter이며 잠금을 사용할 때와 마찬가지로 오류를 올바르게 트래핑하는 것이 좋습니다. 위해 이전 틱에 다시 당신의 DispatcherTimer에서 전화를받지 않고 행사 실행 성공적인을에서

1

는 디스패처 타이머를 다시하는 것이 초기화를 start 전화 dt_Tick 이벤트에 입력 한 후와 틱 이벤트의 끝에서 stop를 완료 DispatcherTimer의 IsEnabled이 다시 true로 설정됩니다.

4

DispatcherTimer 만 디스패처 스레드에서 실행되므로 두 핸들러를 동시에 실행할 수는 없습니다. 물론 대기열에 올려 놓고 다른 하나를 직접 실행할 수도 있습니다. 확인해야합니다.

그러나 DispatcherTimer 웹 서비스 호출을해서는 안됩니다. 백그라운드 스레드에서 수행하십시오. 그렇지 않으면 웹 서비스를 기다리고있는 모든 시간을 업데이트하기 위해 UI가 차단됩니다. 기본적으로 UI 스레드에서 장기 실행 작업을해서는 안됩니다. 여러 다른 타이머 중 하나 (예 : System.Timers.Timer)를 사용하여 스레드 풀 스레드에서 작업을 정기적으로 수행하고 UI에 표시해야하는 데이터가있을 때 디스패처를 사용하여 UI 스레드에 콜백합니다.

물론 여러 스레드에서 여러 번 동시에 새로운 종류의 타이머 발생 문제가 발생할 수 있습니다. 이 문제를 방지하는 한 가지 방법은 AutoReset 속성을 false로 설정하고 현재 타이머의 끝에서 다음 타이머 틱 일정을 예약하는 것입니다.

+0

Windows Phone 용 Silverlight를 사용하고 있다는 것을 잊어 버렸습니다. System.Timers.Timer를 찾을 수 없습니다. – Martin

+0

@Martin : 좋습니다. 대신 System.Threading.Timer를 사용하십시오. 같은 기본 원칙 :) –

+0

마지막 질문 하나 존. System.Timers.Timer를 사용하면 동시에 두 개의 틱 이벤트가 실행될 수 있습니까? – Martin