Question Error “System.ObjectDisposedException: Cannot access a disposed object.”

Cecil

19+ years progress programming and still learning.
OE 11.7.15 Windows 64bit.
I have a situation that I can't reproduce in my development environment, but I can in the UAT and Production.

It quite simple. I call a .net WinForm .cls file and when the user clicks on the "Cancel" button inside the WinForm Button, I execute the Exit() method (System.Windows.Forms.Application:Exit()".

In the calling procedure, after the WAIT-FOR System.Windows.Forms.Application:RUN(winformObject), I delete the object winformObject. This is working absolutely fine except when the user clicks on the Close button in the window in the top right corner, I get the error at the "delete object winformObject line":

Error “System.ObjectDisposedException: Cannot access a disposed object.”​

openedge error deletion of object.PNG
What do I do to resolve this?
 
Last edited:

Osborne

Active Member
I had something similar once, and like you it was only happening in different environments. I was not able to fathom out what was going on but it seemed some sort of repeat was going on and the close/exit was being applied twice. The second close was giving the error as the object did not exist because it had already been disposed by the first close/exit.

To solve I had to apply something similar to this:

Code:
DEFINE VARIABLE formClosed AS LOGICAL INITIAL NO NO-UNDO.

...

IF VALID-OBJECT(oForm) AND NOT formClosed THEN
   oForm:Close().

...

PROCEDURE form_closed:
   DEFINE INPUT PARAMETER sender AS System.Object NO-UNDO.
   DEFINE INPUT PARAMETER e AS System.EventArgs NO-UNDO.

   IF VALID-OBJECT(oForm) THEN
      oForm:Dispose().
END PROCEDURE.

/*------------------------------------------------------------------------------
  Purpose:     Called on the close box of the form
------------------------------------------------------------------------------*/
PROCEDURE form_closing:
   DEFINE INPUT PARAMETER sender AS System.Object NO-UNDO.
   DEFINE INPUT PARAMETER e AS System.Windows.Forms.FormClosingEventArgs NO-UNDO.

   formClosed = TRUE.
END PROCEDURE.

Not ideal but the only way I could solve. Hope this helps.
 

Cecil

19+ years progress programming and still learning.
I've seen this in a Kbase. I hope it might fix it.

Code:
    @VisualDesigner.
    method private void UserAuthorisation_FormClosing( input sender as System.Object, input e as System.Windows.Forms.FormClosingEventArgs ):
        
        if valid-object(components) then
            cast(components, System.IDisposable):Dispose().
        
        return.

    end method.
 

Osborne

Active Member
With what I had to do and what you have found it does seem to suggest that the FormClosing method requires some actions to solve.
 

Cecil

19+ years progress programming and still learning.
Manged to get a solution ( feels like a hack).

Had to change a few things to get the right combination.
  1. Removed all code from the destructor class object in side the win form. Any ABL code inside the destructor was just causing issues.
  2. All the code that was originally inside the destructor had to be moved to the FormClosing Event.
  3. move the deletion of the object (delete object winformObject) to a finally block.
  4. change application:exit() to this-object:close() on the "Cancel" button.
 
Top