2010-05-15 4 views
2

WeakReferences에 관한 질문이 있습니다.WeakReferences에 대한 질문

저는 지금 생성 된 텍스처 개체에 대한 참조를 유지하는 "리소스 관리자"를 작성하는 중입니다. 첫 번째는 allready 추측 수 있으므로 자원 ID와 두 번째 PARAM은 자원 자체에 WeakReference를하다,이다

Dictionary<uint, WeakReference> 

: 나는 같은 사전이있다.

지금 내 자원에는 소유자 (즉, 자원 관리자)로부터 자신을 해방시킬 수있는 방법이 있습니다. 그들은 Resource Manger에서이 참조를 전달하면서 메소드를 호출 할 때 그렇게합니다.

WeakReference result; 
if (m_Resources.TryGetValue(ResourceId, out result)) 
{ 
    if (result.IsAlive) 
    return; 

    (result.Target as Resource).free(); // free for good 

    m_Resources.Remove(ResourceId); 
} 

파트 후 나는 데 문제가 있음 :

if (result.IsAlive) 

는 결코 그가의 그렇다면 즐겨 찾기에 계속 자원 인 경우 ResMgr이 같은 무언가를, 검색을 수행 여전히 리소스에 대한 남은 참조가 있기 때문에 도달했습니다.

문제는 난 단지 문제가되는 자원 중 하나 참조해야합니까, 그리고 그것은 같은 자신을 출시 :

resource.free(); // calls internally its owner (i.e. ResMgr) 
resource = null; 

내가은 "자원"변수가 될 것입니다 참조를 통해 왼쪽,하지만 난 설정할 수 없습니다 같아요 내가 먼저 무료로 전화해야하기 때문에 null로 설정하십시오. 꽤 딜레마 ...

글쎄, 내가 소유하고있는 리소스에 대한 참조를 유지하고 뭔가를 망쳐 놓지 않은 레퍼런스가없는 경우에만 리소스 관리자에게 알려주고 싶다.

내가 어떻게 이런 방식으로 깨끗하게 해결할 수 있을지 궁금하십니까?

추신 : 실제로 참조 횟수를 얻는 방법이 있습니까?

미리 감사드립니다.

제조 임프

답변

1

result.IsAlive가 false의 경우, result.Target가 null이됩니다.

finalizer 및/또는 ConditionalWeakTable을보고 싶을 수도 있습니다. 해결책을 찾는데 도움이 될 수 있습니다.

+0

감사합니다. 꽤 유용합니다. 나는 좋은 자체 정리 데이터 구조에 대해 몰랐다. – impmja

+0

흠, 나는 그것이 단지 .NET 4.0 내에서만 가능하다는 것을 알았다. .. 나쁘다. 그러나 어쨌든 고마워! – impmja

2

caching 또는 참조 카운트를 조사하는 것이 좋습니다. 약한 참조는 결코 캐싱 시스템으로 사용되도록 의도되지 않았습니다.
.NET에는 "참조 횟수"가 없습니다. 객체는 참조되거나 참조되지 않습니다. 실제 참조 횟수가 필요하다면 Rx library에서 RefCountDisposable을 작성하는 것이 좋습니다 (참조 카운트 IDisposable).

+0

글쎄 지금까지 볼 수 있듯이 객체를 캐싱하는 것은 .NET 4.0에서만 가능하지만 지금 당장 3.5를 사용하고 있으며 곧 4.0으로 마이그레이션 할 지 모르겠지만 감사합니다! – impmja

+0

캐싱은 3.5 용 엔터프라이즈 라이브러리에서 사용할 수 있으며, 'RefCountDisposable'은 3.5와 4.0 모두에서 사용할 수 있습니다. –

2

나는 이것을 다르게 처리 할 것이다. 내부적으로 객체에 대한 약 참조를 유지할 수도 있지만, 그 객체에 대한 어려운 참조를 반환 할 것입니다. 소비자는 유일한 참고 자료가 있고 필요하지 않은 경우를 제외하고는 자원 관리자에서 항목을 제거해서는 안됩니다. 그렇지 않으면 시스템은 단순히 참조 된 객체를 제거 할시기를 결정할 수 있어야합니다. 그렇게하면 객체에 대한 (하드) 참조가있는 한 메모리에 남아있게됩니다. 사전에서 삭제할 수 있지만 해당 항목 만 삭제할 수 있습니다. 즉, 다른 소비자가 이전 객체에 대한 참조를 가지고 있더라도 새 객체를 새로 작성해야합니다. 약한 참조가 작동하지 않으면 검색 프로세스에서 개체를 다시 만들어야합니다.

public ResourceManager<T> 
{ 
    private Dictionary<uint,WeakReference> Cache = new Dictionary<uint,WeakReference>(); 

    public T this[uint key] 
    { 
     var obj = (T)this.Cache[key].Target; 
     if (obj == null) 
     { 
      obj = ...recreate resource... 
      this.Cache[key] = obj; 
     } 
     return obj; 
    } 

    public void Remove(uint key) 
    { 
     this.Cache.Remove(key); 
    } 
} 
+0

글쎄, 실제로 소비자가 참조를 무효화하면 사전에 존재하는 강력한 참고 자료를 얻을 수 있습니다. 그리고 나는 어떤 시점에서 그것을 정리해야합니다. 또는 내가 생각하는 것이 재사용이라고 생각합니다. 그 입장? 하지만 실제로 리소스 개체에 대한 IDisposable 인터페이스를 구현해야 실제로 텍스처 개체를 확보 할 수 있습니다. 내 생각은 리소스를 직접 삭제할 수있게하는 것이지만 다시 생각해야 할 것 같습니다. – impmja

+0

IDisposable의 사용법을 추가하여 해결책을 얻었습니다. 감사! – impmja