.Show()设置不应处置的表单时出现ObjectDisposedException [英] ObjectDisposedException when .Show()'ing a form that shouldn't be disposed

查看:100
本文介绍了.Show()设置不应处置的表单时出现ObjectDisposedException的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

ive还检查了其他一些问题,显然最好的解决方案是首先防止导致此问题的行为,但是问题是间歇性的,并且非常难以复制。

ive checked out some of the other questions and obviously the best solution is to prevent the behavior that causes this issue in the first place, but the problem is very intermittent, and very un-reproduceable.

我基本上有一个主要形式,带有子形式。子窗体从主窗体的菜单和/或按钮中显示,如下所示:

I basically have a main form, with sub forms. The sub forms are shown from menus and/or buttons from the main form like so:


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();
    }
}

子表单实际上是主表单(不管是好是坏,我实际上都想更改此设置,但要花很多时间才能做到):

and the sub forms are actually in the main form(for better or worse. i would actually like to change this but would be a considerable amount of time to do so):


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

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

修改了子表单的Dispose函数,以便关闭和 X按钮实际上隐藏了表单,因此我们不必每次都重新创建它。当主屏幕关闭时,它将标志设置为2,因此其他窗体知道可以关闭;

The Dispose function for the sub form is modified so that, the 'close' and 'X' buttons actually hide the form so we dont have to re-create it every time. When the main screen closes, it sets a "flag" to 2, so the other forms know that it is actually ok to close;


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的时间都会导致异常,或者,为什么我的表格会被丢弃?

So, the question is, why would this work over and over and over again flawlessly, but, literally, about every 1/1000 of the time, cause an exception, or rather, why is my form being disposed?

我怀疑垃圾收集器变得混乱了,因为它运行了多个小时后,发生的频率轻微

I had a suspicion that the garbage collector was getting confused, because it occurs slightly more frequently after it has been running for many hours.

推荐答案

没有冒犯,但这似乎是很久以前解决的一个非常复杂的问题。

No offense, but this seems to be a very convoluted solution to a problem that was solved a very long time ago.

除了处置其他一次性物品(而且只有在处置标记为true时才这样),您除了在Dispose()方法中不应做任何事情。因此,我不会修改设计者为您生成的方法。

You shouldn't be doing anything in the Dispose() method other than disposing other disposables (and even then only if the disposing flag is true.) So I would not modify the method that the designer generates for you.

因此,对于您为什么会这样发生的问题的直接答案几乎肯定与垃圾收集器调用您的Dispose的时间有关。

So the immediate answer to your question as to why this is happening is almost certainly related to the timing of the garbage collector calling your Dispose method.

相反,您可能应该考虑使用MDI(多个文档界面)父表单和您的子表单称为MDI子表单。然后可以像这样处理子级中的FormClosing事件。

Instead you should probably consider using a MDI (multiple document interface) parent form and your "sub forms" are called MDI children. You could then handle the FormClosing event in the children like so.

(请注意,如果您反对MDI,则可以使用所有者

(Note that if you are opposed to MDI, you can do basically the same thing by using form Owners.)

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

由于各种原因关闭表格时,例如在代码中关闭,父窗体正在关闭,Windows正在关闭等,则关闭不会被取消。仅当由于用户直接关闭子窗体而关闭窗口时,您才会将其隐藏。

When the form is closing because of various reasons such as closing in code, the parent form is closing, Windows is shutting down, etc. then the closing will not be cancelled. Only when the window is being closed because the user closed the child form directly will you hide it.

要在MDI父级中显示MDI子级,您可以以下:

To show a MDI child inside of a MDI parent, you can do the following:

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

MyChildForm childForm = new MyChildForm();
childForm.MdiParent = parentForm;
childForm.Show();

这篇关于.Show()设置不应处置的表单时出现ObjectDisposedException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆