我正在处理一个现场应用程序的问题。
(不幸的是,这是事后调试 - 我只有这个堆栈跟踪。我个人从未见过这种情况,也无法再现)。
我遇到了这个异常:
message=Cannot access a disposed object.
Object name: 'Button'.
exceptionMessage=Cannot access a disposed object.
Object name: 'Button'.
exceptionDetails=System.ObjectDisposedException: Cannot access a disposed object.
Object name: 'Button'.
at System.Windows.Forms.Control.CreateHandle()
at System.Windows.Forms.Control.get_Handle()
at System.Windows.Forms.Control.PointToScreen(Point p)
at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.ButtonBase.WndProc(Message& m)
at System.Windows.Forms.Button.WndProc(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
exceptionSource=System.Windows.Forms
exceptionTargetSite=Void CreateHandle()
看起来在表单被处理后,鼠标事件到达了表单。
请注意,这个堆栈跟踪中没有我的代码。
我唯一做的奇怪的事情是,在使用ShowModal()时,我往往会相当积极地Dispose()表单(见下文"附言")。
编辑:为了澄清,我使用C++-CLI,所以实际上我不调用Dispose(),而是使用delete运算符。这与调用Dispose()相同。
但我只在ShowModal()返回后才这样做(这应该是安全的,对吧?),而且只有当我完成表单后才这样做。
我认为我读过事件可能会在事件队列中排队,但我不能相信这会是问题。我的意思是,框架肯定必须容忍旧消息吧?我可以想象在压力下,消息可能会积压,而窗口可能随时消失?
有什么想法吗?
如果您甚至能提出复制的方法,那可能会有用。
约翰
附言:
说实话,我从来没有完全理解在Form.ShowDialog()之后调用Dispose()是否是绝对必要的——对我来说,ShowDialog()的MSDN文档有点模棱两可。