참조가 삭제 된 객체에 대한 것인지 확인하는 방법 또는 다른 가벼운 방법이 있습니까?
추신-이것은 단지 호기심입니다 (프로덕션 코드가 아니라 잘 자십시오). 예, ObjectDisposedException
객체의 멤버에 액세스하려고 할 때를 잡을 수 있다는 것을 알고 있습니다 .
참조가 삭제 된 객체에 대한 것인지 확인하는 방법 또는 다른 가벼운 방법이 있습니까?
추신-이것은 단지 호기심입니다 (프로덕션 코드가 아니라 잘 자십시오). 예, ObjectDisposedException
객체의 멤버에 액세스하려고 할 때를 잡을 수 있다는 것을 알고 있습니다 .
Dispose
메서드는 획득했지만 아직 해제하지 않은 모든 리소스를 해제하도록 개체에 지시합니다. 객체가 자원을 보유하지 않는 경우 해당 Dispose
메소드는 일반적으로 아무것도 할 필요가 없습니다. 유형이 선언 void IDisposable.Dispose() {};
하면 IDisposable
인스턴스 당 오버 헤드없이 무시할 수 있습니다 . 호출 후 IsDisposed
참이 될 것으로 예상 되는 속성은 . Dispose
Dispose
IDisposable
먼저 폐기되었는지 여부를 어떻게 확인할 수 있습니까? 그렇지 않다고 가정하고 예외를 잡는 대신? 아니면 어떻게 든 당신은 그것이 폐기되었는지 여부를 항상 알아야 할 수 있도록 평생을 관리해야합니까?
IsDisposed
플래그는 코드가 성공할 수없는 작업에 시간을 낭비하는 것을 방지 하는 데 도움이 될 수 있지만 IsDisposed
검사와 사용 시도 사이에 개체가 삭제되는 경우 예외를 처리해야 합니다.
WeakReference
여기에 관련이있는 것 같습니다. 그것은 정확히 IDipose'd 검출기 아니지만,이 GC'd 있다면 그것은 당신을 말해 주는가
답변:
System.Windows.Forms.Control
이 IsDisposed
되는 재산 후 true로 설정 Dispose()
호출됩니다 . 고유 한 IDisposable 개체에서 유사한 속성을 쉽게 만들 수 있습니다.
이것을 허용하는 내장 된 것은 없습니다. 내부 삭제 플래그를 반영하는 IsDisposed 부울 속성을 노출해야합니다.
public class SimpleCleanup : IDisposable
{
private bool disposed = false;
public bool IsDisposed
{
get
{
return disposed;
}
}
public SimpleCleanup()
{
this.handle = /*...*/;
}
protected virtual void Dispose(bool disposing)
{
if (!disposed)
{
if (disposing)
{
// free only managed resources here
}
// free unmanaged resources here
disposed = true;
}
}
public void Dispose()
{
Dispose(true);
}
}
IDisposablePlus
상속 IDisposable
하고 포함 하는 새 인터페이스 ( 또는 기타) 를 정의하는 데 도움이 됩니다 bool IsDisposed { get; }
. 이렇게하면 어떤 IDisposable
개체가를 지원 하는지 쉽게 알 수 있습니다 IsDisposed
.
그것이 당신의 클래스가 아니고 IsDisposed 속성 (또는 비슷한 것-이름은 단지 관례 일뿐)을 제공하지 않는다면, 당신은 알 수있는 방법이 없습니다.
그러나 그것이 당신의 클래스이고 표준 IDisposable 구현을 따르는 경우 _disposed 또는 _isDisposed 필드를 속성으로 노출하고 확인하십시오.
이 Dispose
메서드는 개체를 버리기 전에 필요한 정리를 수행하는 데 필요합니다. 정리가 필요하지 않은 경우 아무것도 수행 할 필요가 없습니다. Dispose
메서드가 아무 작업도하지 않더라도 객체가 폐기되었는지 여부를 추적하도록 요구하려면 IDisposable
매우 제한적인 이점을 위해 많은 객체가 플래그를 추가해야합니다.
IDisposable
두 가지 속성을 포함 하면 도움이되었을 것입니다. 하나는 객체를 폐기 해야하는지 여부를 표시 하고 하나는 객체가 폐기 로 인해 쓸모 없게 렌더링 되지 않았 음을 나타냅니다 . 처리가 실제로 어떤 작업을 수행하는 객체의 경우 두 값 모두 처음에는 true이고 Dispose
. 처리 할 때 정리할 필요가없는 개체의 경우 첫 번째 메서드는 항상 false를 반환하고 두 번째 메서드는 플래그를 어디에도 저장할 필요없이 항상 true를 반환 할 수 있습니다. 하지만 지금은 .NET에 추가 할 수있는 방법이 없다고 생각합니다.
IDisposable
없는 가장 큰 이유 는 Disposed
호출 Dispose
이 이러한 속성을로 설정하지 않는 객체를 갖는 것이 이상하다고 인식되었을 true
것이지만 해당 객체가 다음과 같은 Dispose
경우 호출 되었는지 여부를 추적하도록 요구했기 때문 이라고 생각 합니다 그렇지 않으면 돌볼 이유가 없을 것이며 상당한 비용을 추가하고 거의 이익을 얻지 못할 것입니다.
나는 이것이 오래된 것을 보았지만 대답을 보지 못했습니다. DataSet과 같은 일부 일회용 개체에는 연결할 수있는 삭제 된 이벤트가 있습니다.
class DisposeSample : IDisposable
{
DataSet myDataSet = new DataSet();
private bool _isDisposed;
public DisposeSample()
{
// attach dispose event for myDataSet
myDataSet.Disposed += MyDataSet_Disposed;
}
private void MyDataSet_Disposed(object sender, EventArgs e)
{
//Event triggers when myDataSet is disposed
_isDisposed = true; // set private bool variable as true
}
public void Dispose()
{
if (!_isDisposed) // only dispose if has not been disposed;
myDataSet?.Dispose(); // only dispose if myDataSet is not null;
}
}
Disposed
이벤트는 System.ComponentModel.IComponent
인터페이스 의 구성원입니다 .
내가 좋아하는 것은 초기화하지 않고 객체를 선언하지만 기본값을 Nothing
. 그런 다음 루프 끝에 다음과 같이 씁니다.
If anObject IsNot Nothing Then anObject.Dispose()
다음은 전체 샘플입니다.
Public Sub Example()
Dim inputPdf As PdfReader = Nothing, inputDoc As Document = Nothing, outputWriter As PdfWriter = Nothing
'code goes here that may or may not end up using all three objects,
' such as when I see that there aren't enough pages in the pdf once I open
' the pdfreader and then abort by jumping to my cleanup routine using a goto ..
GoodExit:
If inputPdf IsNot Nothing Then inputPdf.Dispose()
If inputDoc IsNot Nothing Then inputDoc.Dispose()
If outputWriter IsNot Nothing Then outputWriter.Dispose()
End Sub
이것은 또한 주요 객체를 루틴의 맨 위에 놓고 루틴 내에서 사용한 Try
다음 Finally
블록에 배치하는 데 유용합니다 .
Private Sub Test()
Dim aForm As System.Windows.Forms.Form = Nothing
Try
Dim sName As String = aForm.Name 'null ref should occur
Catch ex As Exception
'got null exception, no doubt
Finally
'proper disposal occurs, error or no error, initialized or not..
If aForm IsNot Nothing Then aForm.Dispose()
End Try
End Sub
Using
성명 을 사용하는 대신이 모든 작업을 수행하는 이유는 무엇 입니까? 이 답변이 작성되었을 때 2013 년에 확실히 존재했습니다.
inputPdf
값 (Nothing 이외)으로 설정 되면 답변 inputPdf
이 폐기 되었는지 여부를 알 수있는 방법이 없습니다 . 폐기 후 설정하여 부분적으로 해결할 수 inputPdf = Nothing
있습니다. 그러나 이것은와 동일한 객체를 가리키는 다른 변수 에는 도움이되지 않습니다 inputPdf
. : 그것은 당신이 할 경우입니다 inputPdf = New PdfReader
, Dim pdf2 As PdfReader = inputPdf
, inputPdf.Dispose
, inputPdf = Nothing
, 여전히 알 수있는 방법이 없을 것입니다 pdf2
(이 같은 목적에 배치된다 inputPdf
).
bool IsDisposed { get; }
선언 이없는 것이 궁금해 보입니다System.IDisposable
.