2012-08-25 1 views
22

확장 된 정적 멤버가있는 클래스가 있으며 그 중 일부는 관리되는 개체와 관리되지 않는 개체에 대한 참조를 유지합니다.C# 정적 멤버는 언제 어떻게 폐기됩니까?

예를 들어, 유형이 참조되는 즉시 정적 생성자가 호출되어 클래스가 Tasks의 blockingQueue를 회전시킵니다. 이것은 정적 메소드 중 하나가 호출 될 때 발생합니다.

IDisposable을 구현 했으므로 내가 만든 모든 인스턴스 개체에서 처리를 처리 할 수있는 방법을 제공합니다. 그러나 소비자가 클래스에서 인스턴스 객체를 만들지 않으면 이러한 메서드가 호출되지 않습니다.

클래스의 정적 부분에서 유지 관리되는 참조를 처리하는 코드를 어떻게 그리고 어디서 처리해야합니까? 나는 마지막 인스턴스 객체가 해제 될 때 정적 참조 된 리소스의 처리가 발생했다고 항상 생각했다. 인스턴스를 만들 수없는 클래스를 만든 적이 처음입니다.

+1

정적 아이템은 어플리케이션의 전체 실행 가능하다. NEW 키워드를 사용하여 정적 항목을 만들지 않으므로 아무 것도 실제로 인스턴스화하지 않기 때문에 아무 것도 여러 인스턴스가 없다는 것을 의미합니다. 관리 대상에 대해서는 걱정하지 마시고 GC가 처리해 드리겠습니다. 관리되지 않는 리소스는 정적이 아닌 클래스에서 사용하려고 시도하거나 응용 프로그램을 닫을 때까지 유지됩니다. 정적 항목은 처분을 지원하지 않습니다. – alexandrudicu

+0

감사합니다. 나는 나의 디자인을 여기에서 재고 할 필요가있는 것처럼 보인다. – Joe

답변

35

클래스를 유지하는 앱 도메인이 언로드 될 때까지 클래스의 정적 변수가 가비지 수집되지 않습니다. Dispose() 메서드는 인스턴스 메서드이며 클래스의 인스턴스를 만들지 않기 때문에 호출되지 않습니다.

Dispose() 메서드를 사용하려면 개체를 싱글 톤으로 만들고 해당 인스턴스를 하나 만들고 응용 프로그램이 종료 될 때 명시 적으로 처리하십시오.

public class MyClass : IDisposable { 
    public IList List1<int> {get; private set;} 
    public IDictionary<string,string> Dict1 {get; private set;} 
    public void Dispose() { 
     // Do something here 
    } 
    public static MyClass Instance {get; private set;} 
    static MyClass() { 
     Instance = new MyClass(); 
    } 
    public static void DisposeInstance() { 
     if (instance != null) { 
      Instance.Dispose(); 
      Instance = null; 
     } 
    } 
} 
+0

그건 의미가 있습니다. 나는 결국이 싱글 톤 패턴을 사용해야 할 것 같아서 ... 당신의 도움에 감사드립니다. – Joe

0

이 개체를 수동으로 처리해야합니다. 정적 리소스에 "마무리 자"를 만들 수있는 방법은 없습니다.

+1

수동으로 어떻게 처리합니까? 이 일을해야한다고 어떻게 알릴 수 있습니까? – Joe

+0

@Joe 전적으로 결정할 사항입니다. 정적으로 개최되는 무언가를 폐기 할 때가 언제인지 알 수 있습니다. – vcsjones

+0

예를 들어, 원래 질문의 예를 참조하십시오. 여기서는 Actions의 blockingQueue를 위로 돌립니다. 이 큐는 사용자가 더 이상 정적 메소드를 통해 작업을 드롭하지 않을 때까지 실행되어야합니다. 내가 더 명확하게 만들자. 대기열을 배수하는 작업을 언제 종료 할 수 있습니까? 그래서 언제 내가 그것을 죽일 수 있습니까? 내 수업이 더 이상 사용자의 "범위"에 없다는 것을 어떻게 알 수 있습니까? – Joe

0
public class Logger : IDisposable 
{ 

    private string _logDirectory = null; 
    private static Logger _instance = null; 

    private Logger() : this(ConfigurationManager.AppSettings["LogDirectory"]) 
    { 
     AppDomain.CurrentDomain.ProcessExit += CurrentDomain_ProcessExit; 
    } 

    private Logger(string logDirectory) 
    { 
    } 

    public static Logger Instance 
    { 
     get 
     { 
      if (_instance == null) 
       _instance = new Logger(); 
      return _instance; 
     } 
    } 

    private void CurrentDomain_ProcessExit(object sender, EventArgs e) 
    { 
     Dispose(); 
    } 



    public void Dispose() 
    { 
     // Dispose unmanaged resources 
    } 
} 
관련 문제