This article was previously published under Q243548
This article has been archived. It is offered "as is" and will no longer be updated.
This article provides several specific guidelines and recommendations for designing Visual Basic COM components to improve performance and scalability under Active Server Pages (ASP).
In general, the following recommendations have proven to resolve numerous problems as well as optimize scalability and performance for Visual Basic components under Active Server Pages (ASP):
Do not store Visual Basic Apartment-Threaded [Single-Threaded Apartment (STA)] objects in Session or Application scope. Storing these objects in Session scope causes future requests for the object by the Session to be handled by the same thread that created the object.
Design stateless components. Preferably, state information should be stored and retrieved from a database. Alternatively, you can pass state information through cookies or ASP requests.For additional information, click the following article number to view the article in the Microsoft Knowledge Base:
175167 How to store state in Active Server Pages applications
For VB components intended for multithreaded environments, for example, IIS, MTS, or COM+, avoid using module level variables in .bas modules, because each thread has its own copy and only objects or requests on the same thread can share them. From an application’s perspective, this causes unpredictable behavior because each user request can potentially be handled by a different thread, which would contain a different value for the variable. See the following resources for more information:
"Multithreading" in the Visual Basic documentation.
Do not use Single-Threaded Visual Basic objects under ASP.
Do not use components that rely on User-Interface elements.
Components should not make any assumptions about the user it's running under to avoid issues with desktop and registry access. Because components run under the System desktop, do not rely on registry keys stored under HKEY_CURRENT_USER. If you need to use the registry, store values under HKEY_LOCAL_MACHINE. A common example of this problem is when you try to print under ASP.For additional information, click the following article number to view the article in the Microsoft Knowledge Base:
184291 COM objects fail to print when called from ASP
Do not use the VBScript functions CreateObject and GetObject in server-side scripts. Use Server.CreateObject instead so that ASP can track the object instance. Objects created by CreateObject or GetObject cannot access the ASP built-in objects and cannot participate in transactions.
You should not put code in the Class_Initialize and Class_Terminate events of an Microsoft Transaction Server (MTS) component that attempts to access the object or its corresponding context object. The Visual Basic run-time environment calls Class_Initialize before the object and its context are activated, so any operations that Class_Initialize attempts to perform on the object or its object context fails. Similarly, the object and its context are deactivated before Class_Terminate is called, so operations that this method attempts on the object and its context also fail. You should not set a breakpoint in the Class_Terminate event of an MTS component. When the debugger reaches the breakpoint, it attempts to activate the object, an attempt fails and causes Visual Basic to stop.
ByRef parameters should be passed as Variant while ByVal parameters can be specific data types.For additional information, click the following article number to view the article in the Microsoft Knowledge Base:
197956 Passing parameters by reference to a VB COM object
Do not register your component with MTS unless you need transactions. ObjectContext can be expensive in terms of performance.
Do not use OnStartPage and OnEndPage methods to access the ASP intrinsics. These methods are provided for legacy support with Internet Information Server (IIS) 3. Use ObjectContext. However, if you have an ActiveX EXE, then you cannot use ObjectContext and must use OnStartPage.
Run your Web applications in a separate memory space, while running your component in a library package. This helps with fault tolerance while minimizing the costly overhead of marshalling.
If you are going across machines or processes, pass your parameters ByVal into your Visual Basic component. This minimizes marshalling overhead.
Include robust error handling in every method. Use Visual Basic's App.LogEvent to record the following information to the EventLog when an error occurs:
Err.Number, Err.Description, Err.Source
Current user (use the GetUserName() API)
Thread Id (use the GetCurrentThreadId() API)
The name of the method where the error occurred.
All argument values in to the method.
The time the error occurred (use the GetTickCount() API).
The source code line number using ERL.
Make sure Unattended Execution is set for both ActiveX EXEs and DLLs. ActiveX DLLs should also have their Threading Model set to Apartment Threaded, and Retain in Memory selected.
During development, use Project Compatibility and select Binary compatibility for release.
For more information, visit the following MSDN Web sites: