2010-02-11 2 views
6

ObjectDisposedException을 모든 기본 노출 메소드의 시작 부분에 조건부로 던질 목적으로 일반 세이프티 유형의 bool disposed 필드를 추적하는 데있어 중요한 점이 있습니까?IDisposable, ObjectDisposedException 및 threadsafe 유형

이 패턴은 온라인 몇 군데에서 권장되는 것으로 보았지만 제작자가 올바르게 사용하고 있는지 확실하지 않으므로이 질문에 해당한다고 가정합니다.

이러한 시나리오에서 조건의 평가를 벗어나는 조건이 참임을 확인하는 유일한 방법은 Dispose() bool) 메소드를 호출합니다. 이렇게하면 유형을 효과적으로 다시 단일 스레드로 만들지 않을까요?

그리고 이것이 사실이라면 사용에 아무런 요점도 없으므로 일부 IDisposable 구현에서 ObjectDisposedException 메커니즘에 의존 할 수 없습니다. 그렇다면 우리는 왜이 메커니즘을 사용하지 않았습니까? 필요한가?

내가는 IDisposable 및 경우 ObjectDisposedException 그냥 스레드 안전 유형 함께하지 않는 것 같아요 ====

.

+0

참조 : http://stackoverflow.com/questions/170028/how-would-you-simplfy-entering-and-exiting-a-readerwriterlock –

답변

4

아마도 메소드가 실행되는 동안 스레드 안전 객체를 처리하지 않는 더 효율적인 방법은 ReaderWriterLockSlim을 사용하는 것입니다. 실행시에 모든 public 메소드가 읽기 락을 취득하도록 (듯이) 해주세요. Dispose에 작가 잠금을 설정하십시오. 쓰기 잠금이되기 전에 다른 모든 메소드가 완료 될 때까지 대기합니다. 그런 다음 독점적으로 보유하는 쓰기 잠금 안에 isDisposed을 설정합니다. Dispose이 완료된 후에 공용 메소드를 호출하면 isDisposed을보고 ObjectDisposedException을 던집니다.

ReaderWriterLockSlim

http://msdn.microsoft.com/en-us/library/system.threading.readerwriterlockslim.aspx

+0

멋진 아이디어. 샘플 가져 왔어? ReaderWriterSlimLock에서 설명서를 찾을 수 없습니다. 이전에 보았던 것입니까, 아니면 방금 브레인 스토밍 한 것입니까? –

+0

브레인 스토밍을 해봤지만 귀하의 요청에 잘 부합해야한다고 생각합니다. 원래의 대답으로 잘못 입력했는데, 그것은'ReaderWriterLockSlim'입니다. MSDN 문서 링크를 추가했습니다. –

+0

사실 FXcop은 ReaderWriterLockSlim이 IDisposable을 구현하고 나머지 객체 자원과 함께 처리되어야한다는 점을 제외하고는 거의 작동합니다. 일단 dispose가 호출되면 객체가 삭제되었는지 테스트하기 위해 더 이상 읽기 잠금을 얻을 수 없습니다. –

3

경우 이미 배치되어있는 경우 개체의 행동이 다른 것, 그것이이 배치 됐어요 후가 사용될 가능성이 있다면, 당신은 계속해야 이걸 추적 해. ObjectDisposedException을 던지는 것이 개체가 이미 삭제되어 있고 처음 확인하지 않은 경우 발생할 임의의 예외를 throw하는 것보다 낫습니다.

+0

네,하지만이 질문은 멀티 스레드 시나리오에서 확실하게 ObjectDisposedException을 던지는 방법에 관한 것입니다. –

+0

@Jason : 그렇다면 질문을 편집하여 그렇게 말하십시오. –

0

"Disposed"부울은 한 곳에서만 업데이트되며 Disposed를 호출 한 후에는 호출자가 해당 객체를 사용하는 버그입니다.

Dispose가 호출 된 후 ObjectDisposedException을 "대부분의 시간"throw하는 것으로 충분하다고 생각합니다. 디버거 도우미 인 ObjectDisposedException은 호출자가 잡아야하는 것이 아니라는 것을 알 수 있습니다.

0

개체가 삭제되는 동안 메서드가 호출 될 가능성이있는 경우 메서드의 의미는 삭제 된 개체에서 메서드를 호출해도 아무런 문제가 발생하지 않도록 정의해야합니다. 문제가 있거나 없을 수도있는 경우 "시도/수행"패턴을 사용해야합니다. Microsoft가 Control.BeginInvoke와 함께이 원칙을 따르면 "Control.BeginInvoke"와 "Control.TryBeginInvoke"가 둘 다 있습니다. 후자는 명시 적으로 false를 리턴하고 액션이 대기열에 추가되기 전에 처리가 중단 된 경우 아무 것도하지 않는 것으로 명시됩니다 (true를 리턴하는 Control.BeginInvoke는 실제로 조치가 실행되기 전에 컨트롤이 처리되지 않을 것이라는 점을 보증하지 않습니다).이 패턴은 디스플레이 업데이트 시나리오와 같이 매우 유용합니다. 컨트롤이 삭제되지 않으면 업데이트 루틴을 실행해야합니다. 그러나 업데이트 루틴이 실행되기 전에 폐기되면 업데이트가 문제가되어 실행 실패가 거의 문제가되지 않습니다.