"Go". NET in STAThread and Mtathread

Source: Internet
Author: User

ref:http://blog.csdn.net/dyllove98/article/details/9735955

1 apartments in COM

This article discusses in-process COM components. Visually demonstrate the roles and differences of STAThread and mtathread in one example.

1.1 Basic Rules

Apartment is the running environment of COM components, the apartment is used for living in the daily life, the apartment in COM is used to live the object of COM component, each COM object must and can only be in one apartment: single-threaded apartment (STA) or multi-threaded apartment (MTA).

Each process can have 0 or more sta.

Each process can have 0 or 1 MTA.

A thread can only be associated to an apartment. So all threads that are associated to the MTA are one MTA that is associated to the process.

This thread accesses the COM object in the STA associated with this thread without requiring a column set for direct access.

Other threads require a column set (marshal) for access to COM objects in the STA, and automatically implement synchronization under multi-threaded access through column sets .

The access of all threads to COM objects in the MTA does not require a column set, direct access, and requires the COM component itself to implement synchronization under multi-threading .

(a column set is a serialization of function calls that implements cross-boundary calls, usually implemented in Windows through a message mechanism.) In COM RPC is a column set, in WinForm Control.Invoke is a column set, remoting is also a column set, WCF is also a column set, the recent popular restfull is also ... )

1.2 Apartment Type Matching

A COM object belongs to the apartment, determined by the configuration of two places: the apartment model and the client thread apartment model .

    1. The component Apartment model is set when the component is registered to the registry, and through the component Apartment model, the component declares what apartment it can live in. Optional options include: Apartment,free and both. Apartment, I can only live in a single-threaded apartment; free, I can only live in multi-threaded apartment; Both, I am casual, single-threaded apartment or multi-threaded apartment.
    2. The client-threaded apartment model is the apartment model of the thread that represents what apartment the current thread provides. Options include: single-threaded apartment (STA) or multi-threaded apartment (MTA), which is the STAThread and Mtathread discussed in this article.

The following table lists the combined tables that the component objects will eventually live in:

Client thread apartment model \ Component Apartment model Apartment Free Both
Sta Sta Mta Sta
Mta Sta Mta Mta

If the component Apartment model is apartment, regardless of the client-side apartment model, the component eventually lives in the STA because the component says "I can only live in a single-threaded apartment". If the current thread is the Mta,com library, an STA is created in the background to put the component's object.

If the component Apartment model is free, regardless of the client-side apartment model, the component eventually lives in the MTA because the component says "I can only live in a multithreaded apartment". If the current thread is the Sta,com library, the MTA that checks the current process is not created, does not create the process's MTA, and then places the component's object in the MTA.

If the component Apartment model is both, the component eventually lives in the apartment associated with the current thread, and if the current thread is STA, it lives in the STA, and when the front end is the MTA, it lives in the MTA. In this article, we create a component that registers a both type, and then create an object for that component in the STA and MTA, respectively.

1.3. NET to set up the client-side apartment model

When you use COM components in. NET, you need to set up the apartment model for the thread.

In. NET you can set the apartment type of the main thread through the STAThread and Mtathread properties, and by thread.setapartmentstate you can set the apartment type of the worker thread.

For WinForm or WPF applications, the apartment model of the main thread must be STA, because the user interface objects are not thread-safe.

For the console application, the main thread of the apartment model can be set at will, for convenience, we use the console application to demonstrate. (with WinForm You can also fully demonstrate that you just need to create the object for the component in the worker thread.) )

2 A simple COM component

To demonstrate the difference between a single-threaded apartment and a multithreaded apartment, we use the ATL implementation to define a simple COM component, simplecom, which contains a method of returning a string hello, the returned string is in three-step synthesis, and each step consumes a longer CPU cycle through the consume method. Make sure that Hello is not done in a time slice of the operating system, and that the Hello function is executed concurrently to achieve the effect of the presentation. The code is as follows:

 1//CSimpleCom.h 2 class atl_no_vtable csimplecom:3 public ccomobjectrootex<ccomsinglethreadmodel>, 4 PU Blic ccomcoclass<csimplecom, &clsid_simplecom>, 5 public iconnectionpointcontainerimpl<csimplecom> 6 public cproxy_isimplecomevents<csimplecom>, 7 public idispatchimpl<isimplecom, &iid_isimplecom, &am P  Libid_atltestlib,/*wmajor =*/1,/*wminor =*/0> 8 {9 public:10 csimplecom () one {This->m_imember = 0;13}14 Declare_registry_resourceid (idr_simplecom), Begin_com_map (csimplecom) com_interface_entry (  isimplecom) com_interface_entry (IDispatch) com_interface_entry (IConnectionPointContainer) End_com_map () 23 24 Begin_connection_point_map (csimplecom) connection_point_entry (__uuidof (_isimplecomevents)) END_CONNECTION_ Point_map () declare_protect_final_construct () FinalConstruct HRESULT () + () }35 $ void FinalrelEase () PNs {}39 public:41 stdmethod (Hello) (bstr* a), private:43 int m_imember;44 CString m_str;4 5};46 Object_entry_auto (__uuidof (simplecom), csimplecom)
1//CSimpleCom.cpp 2 double Cosume () 3 {4     double d = 0; 5 for     (int i = 0; i < 1000*1000*300; i++) 6     {7
   d + = i; 8     } 9     return d;10}11 stdmethodimp Csimplecom::hello (bstr* a) @ m_str     = L "0> Hello! ";     Cosume ();     CString str;17     str. Format (L "1>m_imember =%d; ", this->m_imember++);     m_str + = str;19     cosume ();     m_str + = L" 2> goodbye ";     *a = m_str. AllocSysString ();     return s_ok;23}

Set the component's ThreadingModel to both, build the project, and the component will register automatically.

Next, you create a C # client that uses the component.

3 C # Client

Create a new C # console application that adds a reference to the simplecom component, creates an object for the Simplecom component in the main thread, and invokes the object in both worker threads.

Demonstrates the differences in the behavior of in-process COM component objects in different types of apartments by modifying the apartment type of the main thread.

3.1 Multi-threaded Apartments

The code for creating an Simplecom Component object in a multithreaded apartment is as follows:

 1 namespace ConsoleApplication1 2 {3 class program 4 {5 [Mtathread ()] 6 static void Main (string             [] args) 7 {8 var v = new atltestlib.simplecom (); 9 Thread t = new Thread (x =>10 {One Run ((atltestlib.isimplecom) x); 12});             T.setapartmentstate (ApartmentState.STA); T.start (v); Thread.Sleep (300); 16              Thread t2 = new Thread (x =>17 {Run ((atltestlib.isimplecom) x); 19}); 20 T2. Setapartmentstate (ApartmentState.STA); T2.             Start (v);}23 static public void Run (Atltestlib.isimplecom SC) (try27 {(var i = 0; i < 5; i++) {Console.WriteLine (Strin G.format ("[{0}] {1}", Thread.currentthread.managedthreadid,32 SC. Hello ());}34}35 catch (Exception ex) (Console.writ) Eline (ex); 38}39}40}41}

The results of the operation are as follows:

[3] 0> Hello! 1>m_imember = 0; 1>m_imember = 1; 2> Goodbye ~
[5] 0> Hello! 2> Goodbye ~
[3] 0> Hello! 1>m_imember = 2; 1>m_imember = 3; 2> Goodbye ~
[5] 0> Hello! 2> Goodbye ~
[3] 0> Hello! 1>m_imember = 4; 1>m_imember = 5; 2> Goodbye ~
[5] 0> Hello! 2> Goodbye ~
[3] 0> Hello! 1>m_imember = 6; 1>m_imember = 7; 2> Goodbye ~
[5] 0> Hello! 2> Goodbye ~
[3] 0> Hello! 1>m_imember = 8; 1>m_imember = 9; 2> Goodbye ~
[5] 0> Hello! 1>m_imember = 8; 1>m_imember = 9; 2> Goodbye ~2> Goodbye ~
Please press any key to continue ...

Principle Description:

Because the two-thread code can simultaneously invoke the method of the Component Object V, the value of the M_STR in the component is simultaneously modified by two threads, and the value returned by the Hello method appears chaotic, with the result of a typical lack of synchronization.

3.2 Single-Thread apartments

Single-threaded apartments only need to change the Mtathread in the code above to STAThread.

The output is as follows:

[3] 0> Hello! 1>m_imember = 0; 2> Goodbye ~
[4] 0> Hello! 1>m_imember = 1; 2> Goodbye ~
[3] 0> Hello! 1>m_imember = 2; 2> Goodbye ~
[4] 0> Hello! 1>m_imember = 3; 2> Goodbye ~
[3] 0> Hello! 1>m_imember = 4; 2> Goodbye ~
[4] 0> Hello! 1>m_imember = 5; 2> Goodbye ~
[3] 0> Hello! 1>m_imember = 6; 2> Goodbye ~
[4] 0> Hello! 1>m_imember = 7; 2> Goodbye ~
[3] 0> Hello! 1>m_imember = 8; 2> Goodbye ~
[4] 0> Hello! 1>m_imember = 9; 2> Goodbye ~
Please press any key to continue ...

Principle Description:

Because calls to objects in the STA are set by the COM run-time column, synchronization is automatically implemented for multi-threaded calls.

"Go". NET in STAThread and Mtathread

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.