0

今天我注意到我的代码中有一个错误,我认为我之前已经处理过了。我正在处理应用程序,我经常Windows Forms使用该事件。form_load为了处理Form_load事件中出现问题并引发异常的情况,我使用以下代码:

catch (Exception ex)
{
    LogErrorAndShowMessage(ex, Resources.ERROR_LOAD);

    //Otherwise Error : "Cannot call Close() while doing CreateHandle()".
    this.BeginInvoke(new InvokeDelegate(CloseTheForm));
    LoadForm<Materials>(closeAlreadyOpened : false);
}

这就是我声明委托和方法的方式:

public delegate void InvokeDelegate();//used if form load fails
private void CloseTheForm()
{
    this.Close();
}

从今天开始它运行良好。发生了什么 -Form_load如果我DataSource为我的 ComboBoxes 设置了,并且碰巧从SetDataSource方法中抛出了一个错误,最终导致我在使用之前遇到的完全相同的错误BeginInvoke- Cannot call Close() while doing CreateHandle()

这是异常行为,如果从其他地方抛出异常,代码仍然可以正常工作,只有在设置数据源期间出现错误。

有什么建议可能导致这种异常行为,我该如何解决?

附言

这就是我创建新表单的方式:

protected void LoadForm<T>(ToolStripButton/*ToolStripDropDownButton*/ formButton, 
                           string buttonText, 
                           long? loadEntityId = null, 
                           bool closeAlreadyOpened = true) where T : BaseForm
{
    MainForm parentFrm = GetParentForm();

    if (parentFrm != null)
    {
        if (formButton != null)
        {
            parentFrm.SetForeColor(formButton);
        }

        T openForm = SingletonFormProvider.GetInstance<T>(parentFrm, 
                                                          closeAlreadyOpened);
        openForm.LoadEntityId = loadEntityId;
        openForm.MdiParent = parentFrm;
        openForm.Dock = DockStyle.Fill;
        openForm.Show();
        openForm.Activate();
    }
    else
    {
        MessageBox.Show("Parent form not found!", "Error", 
                        MessageBoxButtons.OK, MessageBoxIcon.Error);
    }
}

也许Hans Passant我应该提出来try-catch解决openForm.Show()这个问题?

4

1 回答 1

5

Load 事件就是这样麻烦。它通常在调用表单的 Show() 方法时触发。但如果表单构造函数中的初始化代码需要创建原生窗口,它可以提前触发。相当不健康,因为表单对象尚未完全初始化。您始终可以通过在 Load 事件处理程序中设置断点并查看调试器的调用堆栈窗口来找出执行此操作的代码。

一般来说,您应该避免 Load 事件,仅在您需要知道窗口的实际大小的极少数情况下才需要它。其他所有内容都属于构造函数,就像它对常规 .NET 类所做的一样。您需要做一些关于捕获和记录异常的事情,最好使用类工厂来完成。样板工厂可能如下所示:

    public static Form1 CreateInstance() {
        try {
            var frm = new Form1();
            frm.Show();
            return frm;
        }
        catch (Exception ex) {
            LogErrorAndShowMessage(ex);
            return null;
        }
    }
于 2013-03-26T17:50:55.347 回答