Custom Class work around. (1 Viewer)

moke123

AWF VIP
Local time
Yesterday, 21:15
Joined
Jan 11, 2013
Messages
1,949
In order to tightly control a data entry procedure I am using a custom class. Within the class I am instantiating several popup forms with withevents for several controls on the forms.
Everything works perfectly so far except for the Class_Terminate event. I declare the class in the forms declarations and instantiate and initialize it with a button click. I put a messagebox in the terminate event to confirm it is firing. The problem is that it fires several times. If I specifically fire it in my class I get the messagebox. If I then run the class again it fires first before the class executes, again when called in the class and again when I close the form.

Researching the issue it seems to be related to a memory leak when using withevents within the class. Something about the cleanup routine failing to clean up all the objects having to do with scope. I've double checked that I set all the objects to nothing in the terminate procedure but it appears to leave some in memory. When I close the form it appears to clean everything up.

Is there an easy way to stop the leaks? As a workaround I am opening a hidden form and declaring and initializing the class in the hidden form. At the competion of my procedure I close the hidden form which fires the terminate event and appears to be cleaning up all the objects as the terminate event only fires one time.
Is this a valid work around?
 

MajP

You've got your good things, and you've got mine.
Local time
Yesterday, 21:15
Joined
May 21, 2018
Messages
3,683
To be clear the Terminate event happens only if an instance of the class goes out of scope. I am confident events do not fire randomly. The terminate event does not fire multiple times. The only way may appear to be firing more than once is if multiple instances are going out of scope. Without seeing your code that calls the class my guess is that your form is keeping a pointer to these objects. Just because the class goes out of scope does not mean all pointers are out of scope. Can you post the class code and the code that instantiate the code.
 

moke123

AWF VIP
Local time
Yesterday, 21:15
Joined
Jan 11, 2013
Messages
1,949
my guess is that your form is keeping a pointer to these objects. Just because the class goes out of scope does not mean all pointers are out of scope.
Thats what I believe I found when researching it. I think they refered to it as memory leaks but I could be wrong.

Attached is an example to demonstarate what I mean. I believe the offending line is - Set ctlMyForm = New Form_Form2

If I comment out the call to class_terminate it will fire when I initialize it for the second time. If I dont comment it out it runs twice.
 

Attachments

  • testClass.accdb
    412 KB · Views: 22

MajP

You've got your good things, and you've got mine.
Local time
Yesterday, 21:15
Joined
May 21, 2018
Messages
3,683
I do not really understand the purpose of this code but I will explain what is happening.

You can call an event procedure and it will execute that code. That does not mean that the event took place. For example assume you have an afterupdate event. You can call that code from somewhere in the code, but that is not going to make an update event take place.
You should never call the class terminate event, it just does not make sense to me. This event happens when the class goes out of scope. In your case you instantiate a class object in your form. This has two class properties. You call the code inside the terminate event which sets these class properties to nothing. However, calling the event procedure is not the same as the event taking place. The class has never terminated. Since it is a module level variable it is still in scope until you close the form that first called it. When you run the code again it instantiates a new instance which terminates the original instance.

The demo shows the above. Once the main form closes out the class goes out of scope.
 

Attachments

  • MajPTestClass.accdb
    408 KB · Views: 20
Last edited:

moke123

AWF VIP
Local time
Yesterday, 21:15
Joined
Jan 11, 2013
Messages
1,949
I do not really understand the purpose of this code but I will explain what is happening.
It was just to demonstrate what I was saying.

The class has never terminated. Since it is a module level variable it is still in scope until you close the form that first called it. When you run the code again it instantiates a new instance which terminates the original instance.
Thats what was bothering me and why I tried calling it. This is what I thought was happening. Thanks for confirming it.
Since the calling form stays open for the majority of any session I didn't like the idea of leaving the class instance in memory. I'm not sure it would make any difference but i always try to close anything not in use.
Once the main form closes out the class goes out of scope.
Given the above I assume my work around of using a hidden form and instantiating the class in its load event and closing the hidden form when the class is no longer needed is acceptable, or at least not crazy.

P.S. I'm still trying to figure out your 2nd class challenge.
 

MajP

You've got your good things, and you've got mine.
Local time
Yesterday, 21:15
Joined
May 21, 2018
Messages
3,683
Given the above I assume my work around of using a hidden form and instantiating the class in its load event and closing the hidden form when the class is no longer needed is acceptable, or at least not crazy.
Sorry, never answered this question. You could accomplish it that way, but probably not necessary if you understand what is happening.

In your first form you have a module level variable, "clsA" for your class "clsTest". When you instantiate the class it has two class properties that also get instantiated. When you were calling the terminate method it was just setting the two class properties to nothing, but ClsA is still in scope. ClsA is in scope and it just has 2 properties that are set to nothing.

From the first form you can simply set ClsA to nothing when done with it. It will then terminate and the terminate event will take place. Using the hidden form is just a convoluted work around. If I instantiate clsA from a hidden form and then close that form then all of its variables go out of scope, so clsA goes out of scope and its terminate event occurs.

You could simply demo this on form1
Code:
Private Sub cmdTerminate_Click()
  Set clsA = Nothing
 'terminate code fires and clsA goes out of scope
End Sub
 

Users who are viewing this thread

Top Bottom