2009-10-05 7 views
1

나는 뭔가를 바보로하고있을 수도 있습니다.이 경우 나는 사과합니다. System.Threading.Timer 클래스로 작업하고 있고 컨트롤 정보를 전달하기 위해 state 개체를 사용하여 타이머를 설정하고 있습니다. 프로그램이 종료 될 때까지 상태 객체가 완료되지 않는다는 것을 제외하고는 모든 것이 예상대로 작동합니다. 이 예는 제가 의미하는 것을 보여줍니다.일회용 System.Threading.Timer 상태가 프로그램 종료시까지 완료되지 않았습니다.

class State 
    : IDisposable 
{ 
    public State() 
    { 
     Console.Out.WriteLine("State.State()"); 
    } 
    ~State() 
    { 
     Console.Out.WriteLine("State.~State()"); 
    } 

    void IDisposable.Dispose() 
    { 
     Console.Out.WriteLine("State.Dispose()"); 
    } 
} 


class Program 
{ 
    public static void Callback(object obj) 
    { 
     Console.Out.WriteLine("entering Callback()"); 

     State state = (State)obj; 

     // . . . // do stuff 

     Console.Out.WriteLine("leaving Callback()"); 
    } 


    public static void Main(string[] args) 
    { 
     Timer t = new Timer(Callback, new State(), 1000, Timeout.Infinite); 

     Thread.Sleep(5000); 

     t.Dispose(); 
     t = null; 
     GC.Collect(10, GCCollectionMode.Forced); // prod GC to release "State" 
     Console.Out.WriteLine("leaving Main()"); 
    } 
} 

이의 출력은 다음과 같습니다

State.State() 
entering Callback() 
leaving Callback() 
leaving Main() 
State.~State() 

내가, 스레드 풀은 그것의 참조 (들)을 공개하지해야 원샷 타이머를 얻을 수있는 Timeout.Infinite 시간을 설정하고 있습니다 때문에 타이머가 디스패치되면 프로그램 상태가 끝날 때까지 대기하지 않고 상태 개체에 저장합니다. 이것은 미묘한 메모리 누수가 될 것이라고 우려하고 있습니다.

저를 계몽하십시오. :-)

+0

Doh! 고마워요. 나는 다시는하지 않을 것이다. – JamieH

답변

-2

C#에서 'finalize'또는 deconstructor는 가비지 수집 및 소멸시에만 호출됩니다. 그때까지 그 함수는 호출되지 않습니다.

예를 들어, GC는 결코 작은 메모리 오버 헤드이므로 실행하지 않아도됩니다.

나는 내가 충분히 특정하지 않았다 것 같아요, 그래서 대신에 무슨 일이 일어나고 있는지 일반화, 나는 행동 설명은 MSDN 문서를 가리키는 것 : 객체가 될 때

http://msdn.microsoft.com/en-us/library/system.object.finalize%28VS.71%29.aspx

의 Finalize를 호출을 "액세스 할 수 없음"(가비지 수집을 통해 실행되지만 실행시기는 보장되지 않음) 또는 응용 프로그램 도메인이 종료 될 때

+1

GC.Collect는 GC를 강제해야하지만 finalizer는 GC 중에 즉시 실행되지 않습니다. 불행히도 CLR에서 파이널 라이 제이션이 어떻게 작동하는지에 대해서는 자세히 기억하지 못합니다. – Michael

관련 문제