[C#] 삭제된 개체에 액세스할 수 없습니다. 해결 방법

'System.ObjectDisposedException' 형식의 예외가 System.Windows.Forms.dll에서 발생했지만 사용자 코드에서 처리되지 않았습니다.
추가 정보: 삭제된 개체에 액세스할 수 없습니다.

해당 오류에 대한 발생 원인 및 해결 방법을 알아봅시다.

우선, 삭제된 개체에 액세스할 수 없습니다. 발생 원인은 문자 그대로 액세스 하려는 개체가 삭제되었기 때문입니다. 폼 개체의 삭제는 보통 Close 메서드와 Dispose 메서드의 명시적 또는 묵시적 호출이 발생한 것으로 이루어집니다.

삭제된 개체에 액세스할 수 없습니다. 해결 방법

삭제된 개체에 액세스할 수 없습니다.

삭제된 개체에 액세스할 수 없습니다 오류를 해결하려면, Close 또는 Dispose 메서드 호출 부분을 점검해 보세요. 해당 클래스가 특정 폼을 상속하고 있다면, 상위 클래스에서 의도치 않은 닫힘 현상이 이루어져 있는 경우도 있습니다. 해당 오류가 발생하는데도, 호출스택을 분석하여도 답이 나오지 않은 경우가 있었는데, 델리게이트에 의한 익명 메서드에서 Close 관련 문제가 발생한 현상을 해결한 기억이 있습니다. 핵심은 두 메서드 또는 Close나 Dispose를 호출할만한 using과 같은 부분을 파악해 보는 것입니다.

Close 메서드와 Dispose 메서드

Close는 System.Windows.Forms 네임스페이스에 있으며, 폼을 닫을 때, 같이 생성되었던 리소스를 close 한 다음에 폼이 dispose 됩니다. 보통 close 메서드는 dispose 메서드까지 암시적으로 같이 호출을 하는데, 특정의 경우에는 dispose가 되지 않기에 명시적으로 호출해야 하는 경우도 있습니다. 예를 들면, 앱이 다중 문서 인터페이스(MDI : multiple document interface)이며, 폼 속성이 보이지 않을 때(visible false), 그리고 ShowDialog 메서드를 호출하였을 때에는 dispose가 실행되지 않습니다. (ShowDialog로 창은 떠있는 상태인데 눈에는 안 보이는 경우입니다.)

Dispose 메서드는 System.ComponentModel 네임스페이스에 있으며, 해당 구성 요소에서 사용하는 모든 리소스를 해제하도록 지시하는 메서드입니다.

폼을 닫는다거나, 리소스를 해제한다는 측면에서 close와 dispose는 비슷하게 사용하는 편입니다.

삭제된 개체에 액세스할 수 없습니다. 예제 소스

폼 개체에 Show 또는 ShowDialog 메서드로 액세스 하려고 할 때, 삭제된 개체에 액세스할 수 없습니다 오류가 발생하도록 예제 소스를 첨부합니다.

class FormBeomSang : Form
{
    internal FormBeomSang()
    {                
        FormClosed += AFormClosed;
        FormClosing += AFormClosing;
    }
    void AFormClosed(object sender, FormClosedEventArgs e)
    {
        Debug.WriteLine("Form Closed");
    }
    void AFormClosing(object sender, FormClosingEventArgs e)
    {
        Debug.WriteLine("Form Closing");
    }
}      

void BeomSang()
{
    FormBeomSang form = new FormBeomSang();           
    FormBeomSang usingForm;
    using (usingForm = new FormBeomSang())
    {

    }
    //usingForm.IsDisposed : True
    Debug.WriteLine($"usingForm.IsDisposed : {usingForm.IsDisposed}");
    //form.IsDisposed : False
    Debug.WriteLine($"form.IsDisposed : {form.IsDisposed}");

    form.Close();
    //삭제된 개체에 액세스할 수 없습니다.
    form.ShowDialog();          
}

댓글