2014-10-20 1 views
1

붙어 콜백 할 일도 :폐기 WaitOne 기능은 내가 그것의 타이머가 타이머 콜백

타이머 :

dataProcessingTimer = new System.Threading.Timer(new TimerCallback(DataProcessingTimerHandler), null, 0, _dataProcessingTimerPollingInterval); 

콜백 : 나는 타이머를 중지 할

void DataProcessingTimerHandler(object param) 
{ 
    // some code.. (sometimes the stop function called from here). 
} 

나는 나의 정지 기능이라고 불렀다 :

public void Stop() 
{ 

    if (_dataProcessingTimer != null) 
    { 
     ManualResetEvent timerDisposeHandler = new ManualResetEvent(false); 
     _dataProcessingTimer.Dispose(timerDisposeHandler); 
     _dataProcessingTimer = null; 

     timerDisposeHandler.WaitOne(); 
    } 

} 

timerDisposeHandler.WaitOne();은 stop 함수 다음에 나오는 코드보다 dispose가 완료되었는지 확인하는 데 사용됩니다.

하지만 때로는 stop 함수가 콜백 중간에 호출되면 waitone이 모두 멈 춥니 다.

WaitOne이 콜백을 고수했는데 왜 발생하는지 이해하지 못하는 것 같습니다. 타이머 콜백이 자체 스레드에서 발견되지 않았습니까? 왜 정지 함수의 스레드가 그것을 붙어해야합니까?

누군가가 내게 상황을 설명하고 해결책을 줄 수 있다면 정말 좋을 것입니다.

답변

1

타이머 콜백에 교착 상태가 발생했습니다. MSDN : "현재 대기중인 모든 콜백이 완료 될 때까지 타이머가 삭제되지 않습니다."

즉, System.Threading.Timer 클래스는 콜백이 완료 될 때까지 자체를 처리하지 않습니다. 그러나 콜백은 Stop() 메서드가 반환 될 때까지 완료를 거부합니다. 그리고 Stop() 메서드는 처리가 완료 될 때까지 반환을 거부합니다.

처분 완료 사실을 알리기 위해 정말로 기다려야하는 경우, 두 가지 옵션이 있습니다. 콜백이 완료 될 때까지 Stop() 호출을 지연합니다. 콜백이 완료 될 때까지 대기를 지연 시키십시오. 무엇 수 없습니다 할 기다리고있는 이벤트를 차단하는 동일한 메서드 내부에서 기다려보십시오보십시오.

IMHO 가장 좋은 해결책은 Dispose()가 완료 될 때까지 기다리지 않는 것입니다. 그 일의 요점은 무엇입니까? 기다려야합니까? 그렇다면 왜?

+0

정지 후 나온 코드가 콜백에있는 데이터를 사용해야하기 때문에 기다려야합니다. 그래서 끝내야합니다. –

+2

콜백에서 수신 한 데이터가 필요한 코드가있는 경우 _definitely_ 콜백에서 Stop()을 호출하지 않으려는 경우가 발생합니다. 이는 대기중인 데드락의 또 다른 계층이기 때문입니다. 콜백이 정지 신호를 보내도록하는 것은 의문 스럽다.하지만 정말로 필요하다고 가정하면 콜백이 나중에/다른 곳에서 실제로 멈춤을 수행 할 코드를 신호하도록 신호를 설정해야한다. 콜백이 수집 한 모든 데이터를 처리합니다. –