System.ObjectDisposedException: 삭제된 개체에 액세스할 수 없습니다. (Form Closed)

윈도우 폼에서 Parent Form을 호출한 다음에, 해당 폼에서 Child Form을 다시 호출하여 delegate를 사용하는 곳에서 System.ObjectDisposedException: 삭제된 개체에 액세스할 수 없습니다. 오류가 발생하였습니다. 자식 개체를 닫을 때 메모리 누수를 보완하기 위해 가비지 컬렉터를 호출하여 dispose 처리하는 부분이 문제로 보입니다. 다시 차일드 폼을 열어서 보여주려고 하니, 오류가 발생하게 됩니다.

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

  • Dispose(disposing);
  • GC.SuppressFinalize(this);
  • GC.Collect();
  • GC.WaitForPendingFinalizers();

문제가 발생한 콜 스택은 다음과 같습니다.

System.ObjectDisposedException: 삭제된 개체에 액세스할 수 없습니다.
개체 이름: 'Child_Form_Name'
   위치: System.Windows.Forms.Control.CreateHandle()
   위치: System.Windows.Forms.Form.CreateHandle()
   위치: System.Windows.Forms.Control.get_Handle()
   위치: System.Windows.Forms.Control.SetVisibleCore(Boolean value)
   위치: System.Windows.Forms.Form.SetVisibleCore(Boolean value)
   위치: System.Windows.Forms.Control.Show()
   위치: Parent_Form_Name.btn_Click(Object sender, EventArgs e)

가비지 컬렉션 호출은 부모 폼을 닫을 때 호출하도록 보완하였으며, 자식 폼에서 닫기를 설정할 때에는 다음과 같이 Closing을 추가하여 안 보이도록 변경처리하였습니다. 눈에만 보이지 않을뿐, 개체가 메모리에 할당되어 있으므로 추후 정리를 하셔야 합니다.

Closing 이벤트에서 e.Cancel = true; 부분은 클로즈드 이벤트를 취소하겠다는 뜻이며, Hide() 메서드를 통하여 Close() 대신 보이지 않도록 효과를 설정하였습니다.

private void Parent_Form_FormClosed(object sender, FormClosedEventArgs e)
{
    ((Form)sender).FormClosed -= Parent_Form_FormClosed;
    FormClosing -= Child_Form_FormClosing;
    //가비지 컬렉터 호출 생략
}

private void Child_Form_FormClosing(object sender, FormClosingEventArgs e)
{
    e.Cancel = true;
    this.Hide();
}
댓글 쓰기
가져가실 때, 출처 표시 부탁드려요! 감사합니다. 💗