15.02.2015 Views

C# 4 and .NET 4

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

710 ❘ ChaPTer 26 interOp<br />

Threading issues<br />

As discussed earlier in this chapter, a COM component marks the apartment (STA or MTA) it wants to live<br />

in, based on whether or not it is implemented as thread - safe. However, the thread has to join an apartment.<br />

What apartment the thread should join can be defi ned with the [STAThread] <strong>and</strong> [MTAThread] attributes,<br />

which can be applied to the Main() method of an application. The attribute [STAThread] means that the<br />

thread joins an STA, whereas the attribute [MTAThread] means that the thread joins an MTA. Joining an<br />

MTA is the default if no attribute is applied.<br />

It is also possible to set the apartment state programmatically with the ApartmentState property of<br />

the Thread class. The ApartmentState property allows you to set a value from the ApartmentState<br />

enumeration. ApartmentState has the possible values STA <strong>and</strong> MTA (<strong>and</strong> Unknown if it wasn ’ t set). Be<br />

aware that the apartment state of a thread can be set only once. If it is set a second time, the second setting<br />

is ignored.<br />

What happens if the thread chooses a different apartment from the apartments<br />

supported by the component The correct apartment for the COM component is<br />

created automatically by the COM runtime. Yet, the performance decreases if the<br />

apartment boundaries are crossed while calling the methods of a component.<br />

adding Connection Points<br />

To see how COM events can be h<strong>and</strong>led in a .<strong>NET</strong> application, the COM component must be extended.<br />

First, you have to add another interface to the interface defi nition fi le COMDemo.idl . The interface<br />

_ICompletedEvents is implemented by the client, which is the .<strong>NET</strong> application, <strong>and</strong> called by the<br />

component. In this example, the method Completed() is called by the component when the calculation<br />

is ready. Such an interface is also known as an outgoing interface. An outgoing interface must be either a<br />

dispatch or a custom interface. Dispatch interfaces are supported by all clients. The custom attribute with<br />

the ID 0F21F359 - AB84 – 41e8 – 9A78 – 36D110E6D2F9 defi nes the name of the interface that will be created<br />

in the RCW. The outgoing interface must also be written to the interfaces supported by the component<br />

inside the coclass section, <strong>and</strong> marked as a source interface:<br />

library COMServerLib<br />

{<br />

importlib(“stdole2.tlb”);<br />

[<br />

uuid(5CFF102B-0961–4EC6–8BB4–759A3AB6EF48),<br />

helpstring(“_ICompletedEvents Interface”),<br />

custom(0F21F359-AB84–41e8–9A78–36D110E6D2F9,<br />

“Wrox.ProCSharp.COMInterop.Server.ICompletedEvents”),<br />

]<br />

dispinterface _ICompletedEvents<br />

{<br />

properties:<br />

methods:<br />

[id(1)] void Completed(void);<br />

};<br />

[<br />

]<br />

uuid(ACB04E72-EB08-4D4A-91D3-34A5DB55D4B4),<br />

helpstring(“COMDemo Class”)<br />

custom(0F21F359-AB84–41e8–9A78–36D110E6D2F9,<br />

“Wrox.ProCSharp.COMInterop.Server.COMDemo”),<br />

www.it-ebooks.info

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!