表格随机处理

时间:2010-12-29 16:22:49

标签: .net vb.net winforms dispose

Protected Overrides Sub LoadForm()
    MyBase.LoadForm()
    Try
        'StartProcess might be causing an error (error msg is issue with loading config, which would be incorrect)
        StartProcess()
        Dim D As New _Delegate(AddressOf SOPERATION)
        Me.Invoke(D)
        BusinessObject = New bConfig(Me)
        CType(BusinessObject, bConfig).LoadKeyValue()
    Catch ex As Exception
        MESSAGES.ShowMessage(MessageIndex.ErrInLoadConfigData, TitleIndex.LoadForm, MessageBoxButtons.OK, MessageBoxIcon.Information)
        StopProcess()
        EnableDisable(CurrentBillType)
    End Try
End Sub

我可以在完全相同的条件下运行100次,看起来像是40次会因以下错误而崩溃:

  

“无法访问已处置的对象。   对象名称:'frmImportExport'。“

它会死在

'within StartProcess()
    Dim __Delegate As New _Delegate(AddressOf StartProcess)
    Me.Invoke(__Delegate)

Dim D As New _Delegate(AddressOf SOPERATION)

我知道在没有看到整个代码的情况下很难回答,但我不能为我的生活找出为什么有时这样做,有时在相同条件下不起作用。关于我能找到什么的任何想法?该论坛不会在我看到的任何地方手动处理,而且此代码正在表单上执行。


其他信息:

  

StackTrace:“at   System.Windows.Forms.Control.MarshaledInvoke(控制   调用者,委托方法,对象[]   args,布尔同步)at   System.Windows.Forms.Control.Invoke(代表   方法,Object [] args)at   ShiftBilling.BaseForm.StartProcess()   在   C:\用户.... \ BaseForm.vb:线   138点   ShiftBilling.frmImportExport.LoadForm()   在   C:\用户\亚历克\工作\的Levelset \ ShiftBillingSource \ ShiftBilling_Source \ JLRBilling \ frmImportExport.vb:行   66“字符串

ShowProcess()的内容并不重要,但这里是代码:

Protected Sub StartProcess()
    If Me.InvokeRequired Then
        Dim __Delegate As New _Delegate(AddressOf StartProcess)
        Me.Invoke(__Delegate)
    Else
        Validator.Clear()
        'If Me.MdiParent IsNot Nothing Then
        IsProcessRunning = True
        frmMain.ShowProgress()
        'CType(Me.MdiParent, frmMain).ShowProgress()
        EnableControls(False)
        'End If
    End If
End Sub

如果它失败,它永远不会到达EndProcess,因此不需要代码。

以下是单击链接以显示表单时执行的代码:

Private Sub ImportExportMenu_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ImportExportMenu.Click
    _frmimport = New frmImportExport
    If clickWindow(_frmimport.Text, _frmimport) = True Then Exit Sub
    _frmimport.Show()
    _frmimport.MdiParent = Me
    SetFormPosition(_frmimport)
End Sub

这是一个要在主窗体中显示的子窗体。

值得注意的是,这是一个外包项目,我只有一天半的工作时间。

4 个答案:

答案 0 :(得分:6)

_frmimport.Show()
_frmimport.MdiParent = Me

这可能是你问题的一部分。 Show()方法强制创建Windows窗口,Handle属性获取值。然后,您可以更改MdiParent属性,该属性需要一个完全不同类型的窗口,即MDI子级。这需要Winforms来销毁Windows窗口并重新创建它。 Handle值会发生变化。同时,您已经启动了一个使用表单的InvokeRequired和Invoke成员的线程。这要求Handle属性有效。这是一个时间问题,这是否会打击。

交换这两个陈述。

答案 1 :(得分:1)

如果您发布更多信息,将会更容易回答。特别是:

  1. 您获得的异常的堆栈跟踪。
  2. 您的Form课程的更多代码,尤其是StartProcessEndProcess方法。
  3. 您是如何展示Form的?您使用的是Application.Run还是Form.ShowDialog
  4. 修改

    这是一个想法:

    覆盖Dispose上的Form,并在其中执行Debugger.Break();之类的操作。 现在再次运行您的应用100次,直到找到您Form处置的原因。 发布显示对Dispose的调用的堆栈trrce。

    修改2

    当问题发生时,你是否会说你手动关闭窗口会更容易... :)

    无论如何,这种行为是设计的。在.NET中,当使用Form创建Form.Show时,当Form关闭时,会自动调用Dispose

    但这对你来说应该不是问题。您实际上不需要将对StartProcess的调用封送到UI线程,因为您在UI线程上 alread

    如果 由于某种原因想要将StartProcess从后台线程封送到UI线程,只需在主窗口上调用Invoke而不是{ {1}}可能已关闭的实例。

答案 2 :(得分:0)

根据提供的信息,您的LoadForm似乎在UI线程上出现。如果是这种情况,为什么你使用Me.Invoke()?如果您在UI线程上,它将立即执行StartProcess()。看起来你自己也在调用StartProcess?这将导致递归。您提供的代码似乎有些不对劲。我同意我们需要看到一些额外代码的其他人。

答案 3 :(得分:0)

错误“无法访问已处置的对象。对象名称:'frmImportExport'。”表示GC收集了frmImportExport,无法访问。从您的代码中可以看出,您将其存储在_frmimport中,但未显示存储位置。也许它存放在临时位置?将该变量共享可能有所帮助。