环境:vb.net visual studio 10 - win forms
错误:
{“无法访问已释放的对象。对象名称:'frmInfo'。”}
堆栈跟踪:
在 System.Windows.Forms.Control.MarshaledInvoke(控制调用者,Delegate 方法,Object[] args,布尔同步)在 System.Windows.Forms.Control.Invoke(Delegate 方法,Object[] args)在 HorizonRealTime.UI.frmInfo R:\csavb2010dlls\Test\TestSoloutions\StoreAutoStuff\HorizonRealTimeVB10\CommanderRealTime.UI\frmInfo.vb 中的 .UpdateGUI(cHorizonColoredString strdata):R:\csavb2010dlls\Test\TestSoloutions\ 中 HorizonRealTime.UI.frmInfo.DoWork() 的第 93 行StoreAutoStuff\HorizonRealTimeVB10\CommanderRealTime.UI\frmInfo.vb:第 75 行在 System.Threading.ThreadHelper.ThreadStart_Context(Object state) 在 System.Threading.ExecutionContext.runTryCode(Object userData) 在 System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode代码,CleanupCode backoutCode,对象 userData)在 System.Threading.ExecutionContext。RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)在 System.Threading.ThreadHelper.ThreadStart()
简单说明:
我有 1 个带有许多子 mdi 表单的主表单。
一种形式(frminfo)管理服务器进程生成的所有状态/错误消息。
这些消息被放置在
Imports System.Collections.Concurrent
Public oStatusMsgs As BlockingCollection(Of String) = New BlockingCollection(Of String) 'thread safe collection
当它进入 if me.invokerequired { me.Invoke(delegate)} 时,问题很少发生(通常只是在应用程序启动时),当它尝试调用自身时,我得到一个对象已处置错误。
即使在调试中,该对象在错误发生后也不会被标记为已处置。
如果我将 me.invoke 包装在 try/catch 中......它会很好地处理以下消息。
文本框中的输出最终看起来像这样:
---Refreshing Data---
#Items Data Refreshed#
#Deps Data Refreshed#
Real-Time Info - Error Displaying GUI Info - #Units Data Refreshed# - Cannot access a disposed object. Object name: 'frmInfo'.
#Retail Data Refreshed#
#Tax Data Refreshed#
---Exiting Data Refresh---
有趣的是,这个文本框在我复制文本的 frminfo 上。
更奇怪的是。它实际上是在收到此错误之前处理消息。因此,已处置的错误异常似乎是错误的读数,实际上正在发生其他事情。
在 frminfo 上是一个低优先级的线程,基本上像这样无限循环
Private sub DoStuff() 'this is kicked off from the frminfo.onload event as a new thread that is referenced by frminfo
dim strdata as string = nothing
do while active
If Me.frmparent.oStatusMsgs.Count > 0 Then
Me.frmparent.oStatusMsgs.TryTake(strdata, 300)
If Not strdata Is Nothing Then
Call me.UpdateGUI(strdata)
End If
strdata = Nothing
End If
thread.sleep(50)
loop
End sub
Private Sub UpdateGUI(ByVal strdata As string)
If Me.InvokeRequired Then
Try
Me.Invoke(New UpdateGUIDelegate(AddressOf UpdateGUI), New Object() {strdata})
Catch ex As Exception
Me.frmparent.oErrorMsgs.Add(Me.Text & " - Error Displaying GUI Info - " & strdata & " - " & ex.Message)
End Try
Else
'this is where it would append the strdata to some kind of textbox or other form level control
end if
end sub
在主 UI 线程上,我确实创建了对此 mdi 子表单的附加引用。
第一个是我添加每个 mdi 子表单的集合。除了添加之外,我让 GC 完全处理这个问题。(我这样做是为了确保我的表单不会被处理掉)
还有一组表格用于对 mdi 子项进行排序。这
在某些情况下,我确实喜欢
dim otmpinfofrm as form = frmcollection(i)
frmcollection(i) = nothing 'where this is where frminfo currently resides in the collection
frmcollection(i) = frmcollection(i+1)
我遍历集合,最后我放回参考
frmcollection(lastindex) = otmpinfofrm
我认为这种排序不会影响调用 me.invoke 来更新本地控件的线程。因为我只是对参考文献进行排序?
对于更好地使用 me.invoke 以避免发生此错误的任何帮助,我们将不胜感激。