Microsoft KB Archive/828988

= A console application that is based on a STA may delay the release of COM components and may delay the calls to the Finalize methods of the objects that the garbage collector collects =

Article ID: 828988

Article Last Modified on 2/9/2004

-

APPLIES TO


 * Microsoft .NET Framework 1.1
 * Microsoft .NET Framework 1.0

-





SYMPTOMS
If a console application that is based on a single-threaded apartment (STA) creates and then uses STA Component Object Model (COM) components and the console application does not perform sufficient operations to pump COM messages, such as calling the Monitor.Enter method, the Thread.Join method, and others, the following symptoms may occur. Also, if the console application performs operations that that run for a long time and that do not pump messages, such as calling the Console.ReadLine method, the following symptoms may occur:
 * The release of COM components may be delayed.
 * The calls to the Finalize methods of the objects that the garbage collector collects may be delayed.
 * Calls to COM components may block the application thread for extended periods.
 * The memory amount that the STA application process uses may increase over time.
 * Calls to the GC.WaitForPendingFinalizers method may take a long time to return.



CAUSE
To deliver a call to a STA COM component correctly, including a call to release the component, the thread where the component was created must be pumping messages. When the managed code no longer references a COM component, the finalizer thread must call the Release method of the component. However, if the STA thread where the component was created is not pumping messages, the call blocks the application until the thread starts pumping messages again. Some applications create a lot of COM components and objects that can be finalized. In these applications, if the finalizer thread spends lot of time blocked while it waits for the STA thread to pump messages, the finalizer thread may not be able to complete its activity. Both the list of COM components to release and the list of managed objects to finalize may grow indefinitely. If this issue occurs, the memory amount that the STA application process uses may increase over time. Also, any thread that calls the GC.WaitForPendingFinalizers method may block indefinitely.

The file and console input/output (IO) operations of the operating system, such as ReadFile and WriteFile, do not pump messages. Because Console.ReadLine relies on the ReadFile API of the operating system, Console.ReadLine does not pump messages either. Therefore, any thread that calls Console.ReadLine does not pump messages during the call.



RESOLUTION
To resolve this issue, use MTA threads instead of STA threads to create and to communicate with COM components in console applications. You can set the main thread of the application to a MTA. To do this, apply the System.MTAThread attribute to the main method, as follows: public class ConsoleApplication {                [MTAThread] static void Main {                    // Add your code here. Console.ReadLine; } } If you must use STA threads to create COM components, the STA threads must pump messages regularly. To pump messages for a short time, call the Thread.Join method, as follows: Thread.CurrentThread.Join(100) This method call pumps messages for 100 milliseconds. You can adjust the time-out based on the requirements of the application. Also, the STA thread should never perform unbounded non-pumping operations, such as calling Console.ReadLine. Instead, the STA thread must have a MTA thread perform the operation and then wait for the operation to finish.

