COMApartment object implements a thread with initialized COM in
              it. By default single-threaded COM is initialized, through the
              Pack1Creator object a multi-threaded apartment thread can be
              created also (for advanced usage only).
              Usually the script and the components created by it are created
              in the same apartment where the script runs. As the apartments are
              related to the threads the only safe and always guaranteed way to
              run an object's method or another script in a separate thread is
              to create it in a COM apartment independent of the apartment where
              the main script runs. So one of the main purposes of the
              COMApartment object is to support the COMThread
              object. To illustrate this lets review this example:
              
                We have a script we want to run in a separate thread. Lets
                put it in a file called thread.js (JScript):
                var Result = "";
function isSimple(n) {
    var j;
    for (j = 2; j <= n/2; j++) {
        if ((n % j) == 0) return false;
    }
    return true;
}
for (i = 0; i < 40000; i++) {
    if (isSimple(i)) {
        Result += String(i) + " ";
        State("Cur") = i + " of 40000";
    }
}
              This code calculates the simple numbers in the range from 1 to
              40000. This will take considerable time and we want to start this
              task in one ASP page and then check how it goes from time to time
              by using another page. Start task page will contain code like this
              (VBScript):
              Set ap = Server.CreateObject("newObjects.utilctls.COMApartment")
Set host = ap.Creator.CreateObject("newObjects.Scphost.ScpMan2")
Set sf = Server.CreateObject("newObjects.utilctls.SFMain")
Set file = sf.OpenFile(Server.MapPath("thread.js"),&H40)
ap.Priority = -15
b = host.LoadEngine("JScript")
If Not b Then Response.Write "FAILED to load the engine<BR>"
b = host.AddText(file.ReadText(-2))
If Not b Then Response.Write "FAILED to load the script<BR>"
host.Add "State", Application
Set Application("Host") = host
Set Application("Ap") = ap
Set thread = Server.CreateObject("newObjects.utilctls.COMThread")
Set Application("Thread") = thread
thread.Activate
thread.Execute host, "Run"
Response.Write "Thread started<BR>"
Response.Write "Thread busy indication: " & thread.Busy & "<BR>"
Set thread = Nothing
              In the code above we create a COMApartment object and we are
              using the Pack1Creator object created automatically in it
              (obtaining it from the Creator property). As this object is
              created in the apartment any object created by it (unless the
              created object is not registered as free-threaded) will be created
              in the same COM apartment. The COMThread
              object internally creates another apartment and calls from it our
              script host component in the first apartment. Thus the both are
              fully independent from the ASP page and the specifics of the ASP
              engine (IIS or ALP) will not interfere.
              To allow communication with the ASP pages we pass the
              Application object to the script that will run in the thread. As
              the Application object is independent from the current page it can
              be accessed directly from the script in the thread and from the
              page. The thread check page will have code like this:
              Set thread = Application("Thread")
If thread.Busy Then
   Response.Write "Thread still busy<BR>"
   Response.Write "Progress: " & Application("Cur") & "<BR>"
Else
    %>
        <H4>Complete</H4>
        <P><%= Application("Host").script.Result %></P>
     <%
End If 
              It only checks the Application value where the progress is
              reported (the "Cur" variable) and also checks if the
              thread is still busy executing the script. If it is busy the
              progress is reported, if the task is complete the result from the
              script is extracted.
              Notes about the sample:
              As it can be seen above the execution of the script is done by
              creating a ScriptManager2
              component, loading the script from the file in it and forcing the
              COMThread object to run it. The statement:
              thread.Execute host, "Run"
              actually means "execute method Run on the object host".
              The method executed may not have arguments. As the method is
              called from the separate thread maintained by the COMThread object
              the ASP page execution will continue while the other script is
              starting too.
              The priority may puzzle you. We want to set lower
              priority to the thread but instead we set the priority for the
              COMApartment and not for the thread - why? (see COM
              Apartments and threads) The call is initiated in the thread
              maintained by the COMThread but it is actually executed in the
              thread maintained by the COMApartment object because of the COM
              synchronization mechanisms. So we tune the execution by tuning the
              apartment and not the initiator thread!
              This will be different if we execute free-threaded object's
              method but scripts must be created in single-threaded apartments
              because they must be called from the thread in which they are
              created.