MORE INFORMATION
Your control is single threaded
Beginning with version 4.0, Internet Explorer requires that all
ActiveX controls it hosts be apartment-threaded. Apartment threading is a
concept from COM; it means that each control exists within its own protected
execution context, or apartment. Internet Explorer requires controls to use at
least a Single-Threaded Apartment (STA), in which all threads except the
control's creating thread can access the control only by posting messages. STAs
make it easy to add concurrency to your ActiveX control with little
programmatic overhead.
Non-apartment threaded controls exhibit uneven
behavior between different instances of Internet Explorer. On some machines,
the control may appear to work fine; on others, its performance slows to a
crawl; and on others, it crashes.
To check whether or not a control
is apartment threaded, consult the Registry entry for the control, and look for
the ThreadingModel value underneath the InprocServer32 key:
HKEY_CLASSES_ROOT\CLSID\{Your Control's CLSID}\InprocServer32\ThreadingModel
This value should be set equal to
Apartment.
If ThreadingModel is not set, your
control is single-threaded. Fortunately, converting your custom control to
apartment threading is an easy change. Consult the topic "apartment-model
threading" in the
MSDN
Library for more information. If you are using a third-party
component, you
cannot just change this registry setting and expect the control to work;
you must get a new version of the control from your component
vendor.
For more information on COM threading models, click the following article number to view the article in the Microsoft Knowledge Base:
150777
INFO: Descriptions and workings of OLE threading models
Your control hosts many other nested controls
Tools like Visual Basic make it easy to create complex ActiveX
controls that contain other controls to multiple levels of embedding. It is not
uncommon to see a developer create a Visual Basic UserControl with dozens of
constituent controls and an embedding hierarchy of seven or eight levels.
However, such controls appear to perform worse on Windows 95 and Windows 98
systems as time goes on, generally causing the browser to crash after about 30
minutes to an hour of dedicated use.
In this case, your control is
using up too many system resources, particularly window handles. Windows 95 and
Windows 98 have a limited amount of space for window handles, which are stored
in a heap contained in the USER32 library. This heap's size is dynamic on
Windows NT, but limited to 32K per process on Windows 95 and 98. Excessive
window handles, combined with a failure to clean up control resources properly
(see below), can quickly exhaust Internet Explorer's window handle limit.
One quick way to solve this problem is to make your controls
windowless. Windowless controls save time and resources by forsaking ownership
of a window handle; in this case, the control's container handles
message-passing for the control through a set of OLE interfaces. Making
controls windowless in Visual Basic, and in Visual C++ frameworks like Active
Template Library (ATL), is very simple. See "Windowless Controls" in the
MSDN
Library for the details. For more information on the architecture of
windowless controls, and what containers must do to support them, see the OLE
Controls 96 specification.
Developers should also re-evaluate their
control's design at this point. Such mammoth controls are hard to maintain and
debug, and developers would best be served by breaking these giant control into
several separate controls.
Your control is not cleaning up resources properly
The more you use complex components (components that contain
n other components), the more likely you are to create circular
references. A circular reference occurs when Control A contains Control B, and
Control B also has a reference back to Control A (say, via a Parent property).
In this case, neither object is destroyed, and thus the DLL containing your
control is never unloaded. It will continue to consume more and more
operating system memory, possibly destabilizing the entire computer.
This is another compelling argument for keeping the design of your controls
flat and simple. In a control with more than four levels of containment,
circular references are hard to track down, requiring tons of manual code
instrumentation and debugging over several days. If breaking up the control is
impossible, formulate a rigorous testing strategy, and verify the safety of
each complex component--starting with the simplest controls and working
up--before building on top of them.