Interop (.NET 1.1) Performance Guidelines - Threading

From Guidance Share
Jump to navigationJump to search

- J.D. Meier, Srinath Vasireddy, Ashish Babbar, and Alex Mackman


Reduce or Avoid Cross-Apartment Calls

When you call a COM object from a managed application, make sure that the managed code's apartment matches the COM object's apartment type. By using matching apartments, you avoid the thread switch associated with cross-apartment calls.

You should create apartment-threaded objects on a managed thread with an apartment type of STA. You should create free-threaded objects on a managed thread with an apartment type of multithreaded apartment (MTA). Objects marked Both can run on either STA or MTA without penalty. Table 7.3 shows the relationship between the component threading model and an unmanaged thread's apartment type.

Table 7.3: Threading Model and Thread Apartment Type

Component Threading Model

Unmanaged Thread's Apartment Type

Single*

STA

Apartment

STA

Both

Either**

Neutral

Either**

Free

MTA

  • *Avoid this where possible. A thread switch may still be necessary if your STA thread is not the Main STA (the first STA thread in the process). In addition, you create contention problems if multiple client threads use single-threaded objects in the same process, because the client threads all share this main STA.
  • * * MTA is recommended. Otherwise, problems may occur. For example, an object's finalizer can block while it waits for STA threads, deadlocks can occur, and so on.

The way in which you set the managed thread's apartment type depends on the type of managed application.


Use ASPCOMPAT When You Call STA Objects from ASP.NET

All .NET threads are MTA threads by default. Therefore, cross-apartment calls and thread switches do not occur when you create and call COM objects with an apartment type of Free, Both, or Neutral. However, cross-apartment calls and thread switches occur when you create and call apartment-threaded COM objects. All objects created with Visual Basic 6 and earlier are apartment-threaded. To call an apartment-threaded COM object from an ASP.NET application without a cross-apartment call and a thread switch, mark your ASP.NET pages with the ASPCOMPAT attribute as follows so that the ASP.NET runtime will process your pages using STA threads.


  <%@Page language="vb" aspcompat="true" %>

Note that you should not instantiate components in the page constructor, because they are executed on an MTA thread before the request is scheduled to use a thread from the STA thread pool. Therefore, instantiating components in the page constructor still incurs an apartment switch along with a thread switch. Instead, you should instantiate them in event handlers such as Page_Load or Page_Init. The components will then be executed on a thread from the STA thread pool.


References

For more information, see Knowledge Base article 308095, "PRB: Creating STA Components in the Constructor in ASP.NET ASPCOMPAT Mode Negatively Affects Performance," at http://support.microsoft.com/default.aspx?scid=kb;en-us;308095.


Calling Apartment-Model Objects from Web Services

Web services created using ASP.NET use MTA threads exclusively, and you cannot change that behavior. That means that using apartment-threaded COM objects, such as Visual Basic 6 components, from an ASP.NET Web service always involves cross-apartment calls and thread-switching. Therefore, if possible, you should avoid using apartment-threaded COM objects from Web services created using ASP.NET. The runtime has been optimized in case you must make cross-apartment calls, but they incur significantly more processing overhead than intra-apartment calls.


Use MTAThread When You Call Free-Threaded Objects

WinForm applications use STA threads by default. Therefore, no thread switches occur when you create and call methods on apartment-threaded COM objects. However, a thread switch occurs when you call free-threaded COM objects. To address this problem, you can switch the default thread type for a WinForm application by using the MTAThread attribute on the entry point method Main as follows.


  [System.MTAThread]
  static void Main()
  {
    Application.Run(new Form1());
  }


Avoid Thread Switches by Using Neutral Apartment COM Components

If you are developing a COM component with C++ that you plan to call from managed code, you should try to create a COM component marked as Neutral. Thread-neutral COM objects always use the caller's thread to execute. A lightweight proxy is used, and no thread switching occurs.