2013-09-23 3 views
3

내 System.Threading.Timer (콜백 포함)는 절대로 안정적으로 실행되지 않습니다. 이것은 타이머가 텍스트 상자에서 실행될 예정인 시간을 입력하는 프로그래밍 할당의 일부입니다.System.Threading.Timer 콜백이 호출되지 않습니다.

System.Threading.Timer timer = new System.Threading.Timer(WorkerObject.callback, null, delay, Timeout.Infinite); 

그리고 지연은 처음 발사 콜백에 대한 지연을 (한 번만 발생하도록되어) 설명하는 단순히 int입니다 :

타이머는 다음과 같이 선언한다.

콜백 방법이 같다 : 스레드를 정지

public static void callback(Object stateinfo) 
{ 
    stop = true; 
} 

효과에 스레드 풀의 스레드에 의해 실행되는 루프 (정지 사실에 플래그를 설정 않는 모든).

루프는 다음과 같습니다

while (!stop) 
{ 
    currentTextbox.Invoke(new Action(delegate() 
    { 
     currentTextbox.AppendText((counter++) + Environment.NewLine); 
     currentTextbox.Update(); 
    })); 
} 

내 문제는 stop 변수가 항상 5000 밀리 초 이상 지연에 대한 잘못된 것입니다. 콜백을 항상 강제로 "강제 실행"할 수있는 방법이 있습니까?

+0

이 질문이 적용되지 않을 수도 있습니다 (API를 잊어 버렸습니다) ...하지만 타이머를 시작합니까? – Jaxidian

+0

프로그램은 타이머가 멈출 때까지 지속적으로 증가하는 카운터를 인쇄합니다. System.Threading.Timer를 시작할 필요가 없습니다. 지연 후 자동으로 시작됩니다 (0은 지연되지 않지만 제 경우에는 지연을 지정했습니다). – docaholic

+0

@Jaxidian : 'System.Threading.Timer'는 사용자가 생성 할 때 시작됩니다. –

답변

9

타이머에 대한 참조를 유지해야합니다.

타이머 개체를 가비지 수집 중일 가능성이 높습니다. 타이머 개체를 종료하고 타이머를 중지합니다.

타이머가 살아 있어야하는 한 참조 번호를 계속 사용하십시오.

+0

+1. 이것은 교활한 문제입니다. 디버거에서 코드를 실행하면 (디버그 또는 릴리스 모드에서) 타이머가 수집되지 않습니다. 하지만 디버거를 연결하지 않고 실행하면 타이머가 수집됩니다. 처음으로 그 사람을 만났을 때 나를 미치게 만들었습니다. –

+1

@JimMischel : 전적으로 동의합니다. 내 기억에 남는 순간은 관리되지 않는 API에 대리인을 전달하는 것이 었습니다. 디버거를 연결하면 모든 것이 잘 작동하지만 디버거가 없으면 GC가 훨씬 더 공격적으로 작동합니다.나는 우리 모두가 우리의 이야기를 가지고 있다고 가정합니다 :) –

+0

그래,이게 정확히 그랬어! @ JimMischel, 디버거에서 동일한 문제가 발생했지만 타이머가 제대로 작동하지만 그렇지 않은 경우 타이머가 가비지 수집됩니다. – docaholic

1

런타임 지터가 while(!stop) 조건을 while(true)으로 최적화하는 중입니다. stop 변수를 휘발성으로 표시하십시오.

private volatile bool stop = false; 
+0

아마 작동 하겠지만 다른 옵션이있을 때는'휘발성 '이라고 제안하지는 않을 것입니다. –

4

내가 사용하는 것이 좋습니다 것 CancellationTokenSource :

static CancellationTokenSource Cancel = new CancellationTokenSource(); 

public static void Callback(object state) 
{ 
    Cancel.Cancel(); 
} 

및 루프 :

while (!Cancel.IsCancellationRequested) 
{ 
    ... 
} 

volatile를 사용하는 것보다 훨씬 깨끗하고, 당신이 당신의 간단한 이동 포트에 쉽게 개념을 증명하여 클래스를 구분합니다. 자세한 내용은 내 블로그 Polling for Cancellation을 참조하십시오.

관련 문제