2010-07-16 2 views
7

추적중인 지식이있는 클래스없이 다양한 클래스의 인스턴스를 추적 할 방법이 필요합니다. 본질적으로 인스턴스를 생성하고 다른 스레드로 넘겨주는 클래스 팩토리가 있습니다. 일단 그 스레드가 인스턴스를 완료하고 언로드하면, 모든 인스턴스가 사라 졌을 때 레퍼런스 카운팅을하고 클래스 팩토리에서 빠져 나오도록 통지받을 필요가 있습니다.개체 처분/파괴에 대한 알림 얻기

도전 과제는 내가 소스 코드를 제어하지 않기 때문에로드하는 클래스를 수정할 수 없다는 것입니다.

내가 만드는 인스턴스를 추적하는 것은 간단합니다. 나는 그것을 만들 때 일종의 컬렉션에 넣을 수 있습니다. 그들의 파괴를 추적하는 것은 나에게 문제를 일으키고있다. 소스 코드를 수정할 수 있다면 각 클래스에 이벤트를 추가하고 인스턴스를 만들 때 이벤트에 연결하여 알림으로 사용합니다. 그러나 나는 그것을 할 수 없다.

그래서 질문은 이것입니다 : 객체 인스턴스를 모니터하고 그것이 파괴되는 것을 감지하는 부끄러운 방법이 있습니까? 당신이 개체의 파괴를 컨트롤에 대한

답변

3

적극적인 알림을받을 방법이 없지만 개체에 WeakReference을 보관하고 주기적으로 확인하십시오.

편집 : 나는 Reed의 대답이 내 것보다 낫다! 당신이 인스턴스에 대한 참조 목록을 누르고 있으면

+0

+1 그게 재밌 네요. 내가 물건을 만드는 것을 통제한다고 말한 부분을 읽을 때까지 나는 똑같은 생각을하고있었습니다.) –

+0

이것은 실제로 내 상황에서 가장 실행 가능한 해결책 인 것처럼 보입니다. 이걸 시험해 볼거야. –

+0

Reed보다 더 좋아합니다. 특별한 장식 자 유형에 대해 알 필요가없는 클라이언트 유형을 의미하기 때문입니다. –

0

방법 : 당신이 개체를 만드는 때문에 당신이 실제 예를 대신 Decorator를 반환 할 수처럼

public void Destroy(T obj) 
{ 
    if (obj == null) 
     throw new ArgumentNullException("obj"); 
    if (!_living.Contains(obj)) 
     throw new ArgumentException("Where did this obj come from?"); 

    using (obj as IDisposable) 
    { 

    } 

    _living.Remove(obj); // List? 
} 
+0

그래서이 파괴()를 호출? 내가로드하는 유형을 제어 할 수 없다는 사실을 기억하십시오 (실제로 폴더에서 동적으로로드되며 실제로 찾을 수있는 것을 미리 알지 못합니다). –

10

것 같습니다.

Decorator Pattern을 사용하면 반환 된 개체를 장식 된 API로 "줄 바꿈"할 수 있습니다. 장식은 파괴 알림을 제공하는 IDisposable 구현을 제공 할 수 있습니다.

+0

좋은 소식입니다. refection을 사용하여 데코레이터를 생성 할 수 있습니다. 클래스가 방대한 경우 이것은 중요합니다. – ChaosPandion

+0

그것은 매우 흥미 롭습니다, 나는 이것을 따라 할 것입니다. 감사. –

2

당신은

이 대신 당신이 GUID 목록을 보유하고 저장소를 만들 수 있습니다 ... 그들은 쓰레기 수집되지 않습니다 그래서 파괴되지 않습니다 생성하고 생성 각 인스턴스에 대한 새 Guid를 작성한 다음 FactoryRepository와 같은 목록에 추가하십시오. 이런 식으로 Guid는 참조 유형이 아닌 구조이므로 가비지 수집에 대한 참조 문제가 없습니다. 그런 다음 각 클래스에서 상속하여 파괴에 대해 알릴 수있는 유형을 만들 수 있습니다. 원래 클래스의 코드를 변경할 수 없으므로이 클래스의 소비자를 변경할 수 없으므로 유형이 호환되지 않기 때문에 (인터페이스를 통해) 데코레이터 패턴과 같은 것이 출력된다고 가정합니다.

아주 간단한 예 :

public class OriginalClassDestroyNotifier : OriginalClass 
{ 
    private readonly Guid _instanceId; 

    public OriginalClassDestroyNotifier(Guid instanceId) 
    { 
     _instanceId = instanceId; 
    } 

    ~OriginalClassDestroyNotifier() 
    { 
     FactoryRepository.NotifyDestroyed(_instanceId); 
    } 
}