Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Does SetAbort really clean up objects? 1

Status
Not open for further replies.

TomSark

MIS
Oct 19, 2000
448
US
NT4/MTS/VB6 environment

I have heard a lot of people recommend that you should explicitly clean up objects that you've created (set them to nothing in VB) instead of relying on SetAbort to completely handle this cleanup.

So, my question is why should you do this? Does SetAbort not clean up everything? Are there bugs in NT or MTS that require you to clean up your objects explicitly? If so, then I can understand the recommendation. If not, then can someone explain why?

Just curious....

Thanks in advance.

Tom
 
You should not clean up onjects explicitly.Call setAbort/setComplete is a good way.These two methods set a flag in ObjectContext which means its work has finished and MTS can pool or clean up it.


Hope this helps you!


 
Hi,

Thanks for responding. A lot of people are telling me that it is wise to do so, although you shouldn't have to, what's the reason for their recommendation?

Thanks,

Tom
 
Actually, I'm beginning to believe that SetAbort does clean things up, but... only if the objects were CREATED within an MTS context. I believe that if you use NEW, in some cases, you should have to set those objects = nothing because Set Complete/Set Abort only cleans up objects created WITHIN the MTS context. If it's possible to create some ojbects OUTSIDE the MTS context, and I believe it is, then you can't exclusively rely on SetComplete/SetAbort to clean everything up.

Tom
 
Right! SetAbort/SetComplete works only in MTS environment.
I think it is better to create objects managed by MTS otherwise you will not benefit from MTS such as transaction support,connection pooling ,object pooling,etc.


Regards!
 
Actually, what I'm implying here is that if you use NEW in an MTS object, SetComplete/SetAbort may not necessarily clean those objects up. If I remember correctly, it matters whether or not those objects were created in your project or not.

Sometimes NEW becomes a CreatObject, sometimes it uses VB object creation code. If you have a case where it uses VB object creation code, then you will have to set the object to Nothing or you will have memory leaks. Sound right?


Tom
 
Nice discussion. But there is something to note. You call SetComplete and SetAbort in the object in which you are doing some task. But you don't release the object in one of its own methods. So as you told, when you are using MTS, there is no need to release the object, since the MTS does not release an object when your task is completed. It just deactivates it and waits for another call to activate your object.

Mohammad Mehran Nikoo
mohmehran@yahoo.com
MCP with experience in VB, ASP, XML, SQL, COM
 
"as NEW" should be avoided when referring to MTS objects. I avoid it entirely. I dimension objects to a specific type during the editing (it's nice to have the auto-help features when you are editing), but comment-out the types before compiling.

"CreateObject" should be used for NON-transactional objects.

The object context and it's "CreateInstance" method should be used to instantiate all transactional MTS objects.

My understanding of .SetAbort and .SetComplete is that they signal MTS to release the objects from memory and do any cleanup that is required. However, I have not seen any indication that a "Set MyOBj = Nothing" will do any harm. I ensure that all objects and set to nothing when exiting a method - including both succesful completion and error handling and have not had any problems with memory leaks.

Hope this is usefull.

Larry
Larryh@ecn.ab.ca

 
Thanks Larry,

You've confirmed my beliefs, however, if one uses NEW, I don't believe that MTS will always clean it up if the Visual Basic object creation code was used to create it. When we go to COM+, I'm told that you should only use CreateObject...

Tom
 
I think the trick to understanding this is to understand that, when a DLL is registered as a component, MTS subtitutes it's own Class ID for the class IDs that were put into the registry by VB when the project was compiled.

When an program uses CreateObject or CreateInstance, the class-ID is looked up and run-time, so the MTS class ID is found and MTS gets the instantiation call. MTS then instantiates a "false front" for the object (the object context). The actual object is only instantiated when a method or property is first referenced. When the object is supposedly destroyed by the calling application, only the false front is initially destroyed. The actual object is kept in memory for x minutes (or indefinitely, if you wish) as a pooled object, and is used to "back-end" the next "false front" that needs an instance of that object.

If you create an object with the NEW keyword, I believe the class code is located ased on the class ID that was obtained when the Project Reference was created, which is the compile-time class ID of the class, and not the MTS-substituted class ID. Thus, NEW circumvents MTS's attempt to intercept the instantiation request, causing the DLL to be laoded into the memory space of your code instead of causing MTS to load the DLL it into it's memory space (MTXAS.EXE, I think).

Another explanation that I have read is that MTS wraps your ActiveX.DLL project with MTS code, effectively changing your ActiveX DLL into an ActiveX EXE, and also adding methods and properties for transaction control and hooks into MTS that give MTS control over the object. Early binding methods use the class IDs of the compiled DLL, while late binding methods use the class IDs of the EXE wrapper. Unless you reference the EXE, any instantiated objects are created outside of MTS's control.

While these two explanations differ in the mechanics (I do not know which is most accurate, the implication is the same. "NEW" circumvents MTS.

Can someone point us to a definitive explanation of the mechanics what happens when a DLL is registered as a component?

Larry
Larryh@ecn.ab.ca

 
That is an excellent explanation, BigLar... I haven't yet heard of the second explanation, however, because of the in-process requirements for MTS I would think that this wouldn't happen.

:)

Tom
 
Actually, I am very confident in the statement that MTS wraps your in-process server (ActiveX DLL), effectively changing it into an out-of-process server. However, I am not sure whether MTS wraps each DLL separately or uses MTX.EXE as a common wrapper for all DLLs, and I not sure whether my comment about finding the different class IDs s accurate.

Under NT, you can see multiple instances of MTX.EXE being created and destroyed as MTS Components are instantiated, used and released.

However, I am a now little confused as to whether As New and New <Object> don't have a place when you are instantiating an object whose class definition is in the same ActiveX DLL project.

Larry
Larryh@ecn.ab.ca

 
> MTS wraps your in-process server (ActiveX DLL), effectively changing
> it into an out-of-process server

Correct, therefore setting to nothing only causes the Release() call to occur and the proxy to be destroyed. The Actual control running in the MTX process may or may not actually be destroyed depending on it's construction and it's configuration within MTS.

Also users should not be calling SetAbort/SetComplete. The logic to determine if the transaction should be Aborted or Completed should be encapsulated within the control and not externalized in the application level code.

Hope this helps
-pete
 
Yes... I am clear now.. this wrapping is what produces the mtx.exe... correct?


Tom
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top