2013-02-03 5 views
2

나는 MyClass 클래스를 가지고 있습니다. 이 클래스는 필드가 있습니다 : public ReaderWriterLockSlim rw; (더 쉬운 예제 코드는 공개). 많은 스레드 등 rw.EnterReadLockIDisposable 및 ReaderWriterLockSlim

또한 내가 구현 한 IDisposable 인터페이스를 사용하여 MyClass에서 데이터를 읽을 수 있습니다 : 하나 개의 스레드가 MyClass를 사용하는 경우

private void Dispose (bool pDisposing) 
{ 
    { 
     if (pDisposing) // release managed resources 
     { 
      if (rw != null) 
      { 
       rwLockSlim.Dispose(); 
       rwLockSlim = null; 
      } 
     } 

     //--- release unmanaged resources 
     // some code... 
     isDisposed = true; // ... 
    } 
} 

당신이 볼처럼이 문제가 될 때 myClass가 개체에 대한 두 번째 스레드 호출 Dispose. ReaderWriterLockSlim은 응용 프로그램을 손상시킬 수 있으므로 처리 할 수 ​​없습니다. 따라서 관리되는 리소스를 해제하는 행을 제거해야합니까? 어쨌든 ReaderWriterLockSlim은 가까운 장래에 GC에 의해 수집 될 것입니다. 맞습니까? (하지만이 클래스 리소스는 값 비싼가요?).
어쩌면 Dispose metod 또는 lock에 lock (syncObject)을 추가해야합니까?

EDIT : 또한 AllocHGlobal을 처리하므로 모든 스레드가 읽기/쓰기가 myClass으로 중단 될 때까지 기다려야합니다. 보기의

다른 점은 :

public MyClass : IDisposable 
{ 
      public void EnterReadLock(); // calls rwLockSlim.EnterReadLock, 
              // if object is disposed throws Exception 

      public void ExitReadLock(); // same as above 

      public void Dispose();  // wait until all threads exit from locks, 
              // frees unamanged resources, mark class as disposed 
} 

답변

1

이것은 최선의 답이 아니라 관찰과 몇 가지 생각하지 않을 수 있습니다.

코드를 단순화 할 수 있습니까? 다른 유형은 특정 동시성 조건에서 예외가 발생하는지 상관하지 않아야합니다. 이걸 어떻게 시험해볼거야? 공용 잠금 객체는 악합니다. 이 은 신비한 버그를 찾아내는 데 몇 달을 소비하고 싶지 않으면해야합니다.

dispose 메서드가 호출되면 다른 개체가이 개체를 사용해야한다는 것을 의미합니다. 즉, dispose 메소드를 호출하기 전에 먼저 모든 스레드가 객체에서 작업을 완료했는지 확인해야합니다.

제안

  • 사용을 고려
  • 안전 행동에 대한 시간 제한을 추가 처리하기 위해 호출하기 전에 잠금 개인
  • 모든 스레드가 완료되어 있는지 확인하십시오 정적 락 객체
  • ReaderWriterLockSlim 리소스 비용이 많이 드는 것은 아닙니다. (애플리케이션에서주의해야 할 점까지)
  • 클래스에서 일회용 리소스를 사용하는 경우 대개 IDisposable을 구현하고 삭제해야하는 멤버를 처리하는 것이 좋습니다.
  • Dispose 메서드에 자물쇠를 추가하지 마십시오. 간단합니다. 이로 인해 불쾌한 버그가 발생할 수 있습니다. Dispose를 수동으로 호출하는 것을 잊어 버리면 GC에 의해 비 결정적으로 호출됩니다 (Finiliser를 통해 추가 호출해야 함).
  • 모든 스레드가 완료되고 처리 될 때까지 대기하는 것이 올바른 방법입니다 객체
+0

공개 ReaderWriterLockSlim은 예를 들어 목적으로 만 사용되었습니다. 두 번째 예제에서 보았 듯이 rwLockSlim.EnterReadLock()을 호출하는 EnterReadLock() 메서드를 만들었습니다. 어쨌든 귀하의 답변에있는 모든 제안에 감사드립니다. – zgnilec

+0

나는 또한 이와 같은 구조를 피하려고 노력할 것이다.당신이 여러 스레드에서 MyClass 클래스의 단일 인스턴스를 사용하는 것처럼 보일 수 있습니다. 괜찮습니다. 하지만 그렇게한다면 메소드를 쓰레드 안전하게 만들고'EnterReadLock'과'ExitReadLock'을 적절히 실행하는 다른 코드에 의존하지 마십시오. – Dirk

+0

'Dispose'를 호출하기 전에 스레드가 끝날 때까지 기다려야하는 경우도 있지만, 통신과 같은 일부 차단 API가있는 경우가 있습니다. 여기서 Dispose는 객체에 대해 호출 될 수있는 * 유일한 * 메소드입니다. (장치가 재구성 될 때까지 사용할 수없는 상태로 장치를 두지 않고 장치를 취소 할 수있는 방법이 없습니다). 이 패턴에서, busy 상태 인 객체에 대해 Dispose를 호출하면 진행중인 작업이 예외를 throw해야합니다. – supercat