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:
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:
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:
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.