|
code
newsgroups
|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
Class AccessIt all seems to work but I occasionally have a weird thing happen. The code runs through Class_Terminate before Class_Initialize. I do not see why but it may be because I am working in the IDE and maybe this app is not closing as I thought or does the Set cEntry = Me make a double instantiation? There is no Main module and this does not start, Class_Initialize, until the app is instantiated in the main program. This is one of the ActiveX that do not want to terminate. All the others do what they are supposed to. The entry class named 'Entry' has this: ' ================================================= Public Event DevStatus(sStatus As String) Private Sub Class_Initialize() Set cEntry = Me ' to allow access from ' modules back to this class Startup ' code in module End Sub 'Class_Initialize Private Sub Class_Terminate() On Error GoTo Class_TerminateErr ShutDown ' code in module Set cEntry = Nothing Class_TerminateExit: Exit Sub Class_TerminateErr: Debug.Assert False Resume Class_TerminateExit End Sub 'Class_Terminate Friend Sub StatusMsg(sMsg As String) RaiseEvent DevStatus(sMsg) End Sub 'StatusMsg ' ================================================= The module mdlEntry has this: ' ================================================= Public cEntry As Entry Private Sub Msg(sMsg as String) cEntry.StatusMsg sMsg End Sub ' ================================================= On Sun, 08 Aug 2010 16:58:38 -0700, BeeJ <nospam@nowhere.com> wrote:
>I have some ActiveX code, both EXE and DLL that I wrote. Not a double instantiation - but does call Terminate.>It all seems to work but I occasionally have a weird thing happen. >The code runs through Class_Terminate before Class_Initialize. >I do not see why but it may be because I am working in the IDE and >maybe this app is not closing as I thought or does the Set cEntry = Me >make a double instantiation? The Initialize event is fired only once when the object is created. Re-assigning to new references doesn't fire the event. However, the Terminate event is fired when the object is set to Nothing, when the last referenced object is 're-set' to a new reference using the Set/New, or when it is re-assigned to a new instance. -ralph ralph pretended :
> On Sun, 08 Aug 2010 16:58:38 -0700, BeeJ <nospam@nowhere.com> wrote: <snip>> >> I have some ActiveX code, both EXE and DLL that I wrote. >> It all seems to work but I occasionally have a weird thing happen. >> The code runs through Class_Terminate before Class_Initialize. >> I do not see why but it may be because I am working in the IDE and >> maybe this app is not closing as I thought or does the Set cEntry = Me >> make a double instantiation? > > > I think your trying to say that the terminate event fires when the last > However, the Terminate event is fired when the object is set to > Nothing, when the last referenced object is 're-set' to a new > reference using the Set/New, or when it is re-assigned to a new > instance. reference is released - correct? Just to be clear - doing a Set cEntry = Me would cause the reference count of the object pointed to by me to be incremented by one. And then when cEntry went out of scope, the reference count would be reduced by one - but, the terminate event would not fire... Since the Me reference is still arround. One cause of the described behavior maybe a circular reference.... That can definately cause a memory leak and an exe to hang around in memory rather then shutdown properly. Hard to know without seeing some code though.... -- Tom Shelton Tom Shelton expressed precisely :
Show quoteHide quote > ralph pretended : On exiting, in Class_Terminate I do>> On Sun, 08 Aug 2010 16:58:38 -0700, BeeJ <nospam@nowhere.com> wrote: >> >>> I have some ActiveX code, both EXE and DLL that I wrote. >>> It all seems to work but I occasionally have a weird thing happen. >>> The code runs through Class_Terminate before Class_Initialize. >>> I do not see why but it may be because I am working in the IDE and maybe >>> this app is not closing as I thought or does the Set cEntry = Me make a >>> double instantiation? >> >> > > <snip> > >> >> However, the Terminate event is fired when the object is set to >> Nothing, when the last referenced object is 're-set' to a new >> reference using the Set/New, or when it is re-assigned to a new >> instance. > > I think your trying to say that the terminate event fires when the last > reference is released - correct? > > Just to be clear - doing a Set cEntry = Me would cause the reference count of > the object pointed to by me to be incremented by one. And then when cEntry > went out of scope, the reference count would be reduced by one - but, the > terminate event would not fire... Since the Me reference is still arround. > > One cause of the described behavior maybe a circular reference.... That can > definately cause a memory leak and an exe to hang around in memory rather > then shutdown properly. Hard to know without seeing some code though.... Set cEntry = Nothing So that should decrement. On 09/08/2010 17:17, BeeJ wrote:
> On exiting, in Class_Terminate I do It will never decrement as cEntry still has a reference to it so the > > Set cEntry = Nothing > > So that should decrement. Terminate event will never be called. You must have an explicit "Close" method that unsets cEntry and allows it to terminate. -- Dee Earley (dee.ear***@icode.co.uk) i-Catcher Development Team iCode Systems (Replies direct to my email address will be ignored. Please reply to the group.) "BeeJ" <nospam@live.com> wrote I would think not. The class that is terminating is cEntry.> On exiting, in Class_Terminate I do > > Set cEntry = Nothing > > So that should decrement. In order for cEntry to terminate, all references to it have to be realeased. My point is, that at that point in time, cEntry should essentially already be Nothing, so setting it to Nothing again, has no effect. You did not show your class instantiation in your first post. Where are you creating the first instance of that class? LFS I use this in several places.
Case 1: the main form instantiates this. Dim cEntry as Entry ' e.g. within a sub Set cEntry = New Entry ' Case 2: the main app instantiates an ActiveX EXE using early binding. Private WithEvents cEntry as Ax.Entry Set cEntry = New Ax.Entry Now I am working with Case 2. On Tue, 10 Aug 2010 07:51:30 -0700, BeeJ <nospam@live.com> wrote:
Show quoteHide quote >I use this in several places. Abandon 'thought experiments'.> >Case 1: the main form instantiates this. > > Dim cEntry as Entry ' e.g. within a sub > > Set cEntry = New Entry ' > >Case 2: the main app instantiates an ActiveX EXE using early binding. > > Private WithEvents cEntry as Ax.Entry > > Set cEntry = New Ax.Entry > > >Now I am working with Case 2. > Create a simple test suite, one client exe, one ActiveX exe. With one object - MyClass. Add a message/logger to the Initialize and Terminate events in MyClass. It is also helpful to provide a static 'count'. Duplicate the same basic calling/creating/destruction architecture, but leave out the rest of the code. (The VB Class Builder is very useful for generating this MyClass object with 'debug' code.) Then run it with both projects open and watch the sequence of events. You are bound to be surprised. You may need to move to a Proxy or Mediator pattern. -ralph "BeeJ" <nospam@live.com> wrote Then, every time you call up a 'new' copy, the first thing it does> I use this in several places. > > Case 1: the main form instantiates this. > > Dim cEntry as Entry ' e.g. within a sub > > Set cEntry = New Entry ' is this: Private Sub Class_Initialize() Set cEntry = Me ' to allow access from ' modules back to this class Startup ' code in module End Sub 'Class_Initialize Which in effect wipes out the old instance in favor of the new. Try this instead: In the module (mdlEntry) where you have: Public cEntry As Entry Private Sub Msg(sMsg as String) cEntry.StatusMsg sMsg End Sub Use this: '============ Private mEntry As Entry Private Sub Msg(sMsg as String) cEntry.StatusMsg sMsg End Sub Public Property Get cEntry() As Entry If mEntry Is Nothing then Set mEntry = New Entry Set cEntry = mEntry End Property Public Sub CleanUp() Set mEntry = Nothing End Sub '================ Then, you'll never need to create an instance, and you will be gaurenteed to be be using only one instance. When its time to close down, call the CleanUp routine to release that one copy of Entry. LFS Show quoteHide quote > > Case 2: the main app instantiates an ActiveX EXE using early binding. > > Private WithEvents cEntry as Ax.Entry > > Set cEntry = New Ax.Entry > > > Now I am working with Case 2. > >
ini in app.pth works for xp, best practice for Vista/W7?
compile error Only udts defined in public object modules can be coerced ... Make a Backup Old VB Project doesn't work with New Office or Windows 7 Reconnection issue between Winsock Server(VB6) and TCP Client (VB.NET) Cleanup remnants Instantiation Any thoughts? Application error .data not place into memory because of an I/O error Error 32765 RegClean Revisited |
|||||||||||||||||||||||