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