ObjectDisposedException from .NET Core Code

I have a problem with the current application.

(Unfortunately, this is delayed debugging - I only have this stack trace. I have never seen this in person and cannot reproduce it).

I get this exception:

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

It looks like the mouse event appears on the form after the form has been deleted.

Please note that this stack trace does not have my code.

The only strange thing (?) That I do is that I use Dispose () forms quite aggressively when I use them with ShowModal () (see below).

EDIT: Just for clarification, I use the C ++ - CLI, so in fact I don't call Dispose () I use the delete operator. This is the same as calling Dispose ().

But I only do this after returning ShowModal () (should it be safe?) And only when I am done with the form.

I think I read that events can be queued in the event queue, but I cannot believe that this will be a problem. I mean, should the structure be tolerant of old messages? I can well imagine that with stressful messages it can go back and, of course, the window can go away at any time?

Any ideas?

If you can even suggest ways to play, this might be helpful.

John


Besides

TBH I never understood whether the call to Dispose () after Form.ShowDialog () is strictly necessary - the MSDN documents for ShowDialog (), in my opinion, are a bit ambiguous.

+4
source share
7 answers

This happens if you show the form after it is deleted. (I tried)

After calling ShowDialog you should delete the form, but only if you do not plan to do anything else with this instance.

+1
source

This is a very strange call stack. The button has been removed, its PointToScreen () method recreates the handle. But he should not have received a hint if it was deleted. Only carving can really explain this.

In addition, by the time the prompt message appeared, nothing should have been deleted. Presumably, this is a button in a dialog box that closes it. Make sure you use the Click event, not the MouseDown event. Also, make sure you close the dialog by setting its DialogResult property rather than calling Close (). It is embarrassing in C ++ / CLI because it does not store separate separate character tables for types and variables.

Ask the user what โ€œimprovementsโ€ she received on this machine.

+1
source

I found your question while diagnosing a similar odd stack trace in my application. Here is the stack trace I had to work with:

 System.ObjectDisposedException: Cannot access a disposed object. Object name: 'TextBox'. at System.Windows.Forms.Control.CreateHandle() at System.Windows.Forms.TextBoxBase.CreateHandle() at System.Windows.Forms.Control.get_Handle() at System.Windows.Forms.Control.set_CaptureInternal(Boolean value) at System.Windows.Forms.Control.WmMouseDown(Message& m, MouseButtons button, Int32 clicks) at System.Windows.Forms.Control.WndProc(Message& m) at System.Windows.Forms.TextBoxBase.WndProc(Message& m) at System.Windows.Forms.TextBox.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) 

This is not the same as yours, but it has the same key characteristics:

  • The handle exists at the beginning, but not at the end of the stack trace.
  • None of my codes appear in the stack trace.

I donโ€™t think my problem is the same as yours, but I thought I would share what I found in the hope that this might give you some idea. After some experimentation, I was able to reproduce my problem. I connected the LostFocus event to another control, and in certain situations, the LostFocus event handler will remove certain controls that are no longer relevant.

However, if the LostFocus event was triggered because the user clicked on one of the controls that need to be removed, I get the stack trace above. In my case, Control.WndProc calls Control.WmKillFocus, which ultimately calls my LostFocus event handler (another control), I delete the control that was pressed, and then Control.WmMouseDown is called.

Perhaps a similar situation arose when something starts before WmMouseUp?

Using the .NET Reflector to view events that might be triggered before WmMouseUp helps you identify a problem.

+1
source

I had this problem with a subclass of Button that I wrote. For me, the solution turned out to check the IsDisposed property of the button between my call to base.OnMouseDown and the rest of the code in the method.

Something like that:

 protected override void OnMouseUp(System.Windows.Forms.MouseEventArgs mevent) { base.OnMouseUp(mevent); if (this.IsDisposed) { return; } } 
+1
source

Why don't you use your form initialization inside the using statement? This will avoid the need to call dispose and ensure its execution at the right time.

eg. (not verified, do not have access to the compiler right now)

 using(FormX frm = new FormX()) { DialogResult res = frm.ShowDialog(); // Do your other stuff after } 
0
source

I had the same problem when I called the Close() method when I clicked a button for a modeless form. Debugging the FlatStyle assembly led me to the FlatStyle button. Do you have a button.FlatSyle = FlatStyle.System ?

For some reason, sometimes the button does not return WM_KILLFOCUS (OnLostFocus) while closing and deleting the form. And if you have button.FlatSyle = FlatStyle.System , this can lead to an ObjectDisposedException with such a call.

0
source

It looks like the mouse event appears on the form after the form has been deleted.

Yes indeed! The exception clearly states: "It is not possible to access the located object, the name of the object is the button", which means that the button that was already located is again under pressure from the order, hence the exception. Therefore, based on the stack trace provided by you, if you notice the bottom line, it is obvious that the second repeating object is located on the already located button during the OnMouseUp button event.

  at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent) 

Therefore, I suggest creating a custom button that inherits from System.Windows.Forms.Button and cancels the OnMouseUp event, in which you prevent re-deletion based on the IsDisposed Button property, as shown below.

 public class FlatSylteSystemButton : System.Windows.Forms.Button { public FlatStyleSystemButton() { this.FlatStyle =FlatStyle.System; } protected override void OnMouseUp(MouseEventArgs mevent) { if(!this.IsDisposed) { base.OnMouseUp(mevent); } } } 

Hope this helps!

0
source

Source: https://habr.com/ru/post/1309330/


All Articles