簡體   English   中英

當.Show()表示不應該處理的表單時,ObjectDisposedException

[英]ObjectDisposedException when .Show()'ing a form that shouldn't be disposed

我已經檢查了一些其他問題,顯然最好的解決方案是首先防止導致此問題的行為,但問題是非常間歇性的,並且非常不可重現。

我基本上有一個主表單,子表單。 從主窗體的菜單和/或按鈕顯示子窗體,如下所示:


private void myToolStripMenuItem_Click(object sender, EventArgs e)
{
    try
    {
        xDataForm.Show();
        xDataForm.Activate();
    }
    catch (ObjectDisposedException)
    {
        MessageBox.Show("ERROR 10103");
        ErrorLogging newLogger = new ErrorLogging("10103");
        Thread errorThread = new Thread(ErrorLogging.writeErrorToLog);
        errorThread.Start();
    }
}

並且子表單實際上是主要形式(無論好壞。我實際上想改變它,但這將是相當長的時間):


public partial class FormMainScreen : Form
{
    Form xDataForm = new xData();
    ...(lots more here)

    public FormMainScreen(int pCount, string pName)
 {
        InitializeComponent();
        ...
 }
    ...
}

子表單的Dispose函數被修改,以便'close'和'X'按鈕實際隱藏表單,所以我們不必每次都重新創建它。 當主屏幕關閉時,它將“標志”設置為2,因此其他形式知道它實際上可以關閉;


protected override void Dispose(bool disposing)
{
    if (FormMainScreen.isExiting == 2) 
    {
        if (disposing && (components != null))
        {
            components.Dispose();
        }
        base.Dispose(disposing);
    }
    else
    {
        if (xData.ActiveForm != null)
        {
            xData.ActiveForm.Hide();
        }
    }
}

所以,問題是,為什么這種方法會一遍又一遍地完美無缺,但是,從字面上講,大約每1/1000個時間都會引起異常,或者更確切地說,為什么我的表格會被處理?

more frequently after it has been running for many hours. 我有一個懷疑,垃圾收集器是感到困惑,因為它會出現更頻繁它已經運行了幾個小時后。

沒有冒犯,但這似乎是很久以前解決的問題的一個非常復雜的解決方案。

除了處理其他一次性用品之外,你不應該在Dispose()方法中做任何事情(即使只有在處置標志為真時才這樣做。)所以我不會修改設計者為你生成的方法。

因此,關於為什么會發生這種情況的問題的直接答案幾乎肯定與垃圾收集器調用Dispose方法的時間有關。

相反,您應該考慮使用MDI( 多文檔界面 )父表單,而您的“子表單”稱為MDI子表單。 然后,您可以像這樣處理子項中的FormClosing事件。

(請注意,如果您反對MDI,則可以使用表單所有者執行基本相同的操作。)

// MDI child
private void Form_FormClosing(object sender, FormClosingEventArgs e) {
    if (e.CloseReason == CloseReason.UserClosing) {
        e.Cancel = true;
        Hide();
    }
}

當表單因各種原因關閉時,例如關閉代碼,父表單正在關閉,Windows正在關閉等等,那么結束將不會被取消。 僅當窗口因為用戶直接關閉子窗體而關閉時才會隱藏它。

要在MDI父級內部顯示MDI子級,您可以執行以下操作:

MyParentForm parentForm = new MyParentForm();
parentForm.IsMdiContainer = true;
parentForm.Show();

MyChildForm childForm = new MyChildForm();
childForm.MdiParent = parentForm;
childForm.Show();
try 
{
    // Validate form not disposed before using. Initialize as needed. 
    if  (xDataForm == null || xDataForm.IsDisposed)
    {
        xDataForm = new MyDataFormName();
    }
    xDataForm.Show(); 
    xDataForm.Activate(); 
} 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM