COM套間對.NET程序使用COM對象的影響(下)

由於所有的COM對象都會被分配到一個相應的套間裏面,因此在.NET裏面,爲了方便.NET程序調用COM對象,每一個.NET線程都會被分配到一個套間裏面――即使你沒有在代碼裏面指定線程運行的套間。在.NET線程裏面創建的COM對象都會被分配到特定的套間裏面,如果兩個.NET線程 被分配到了不同的套間裏,那麼兩個線程之間互相調用COM對象就需要列集函數調用。

.NET 2.0以後,默認情況下.NET的線程是運行在多套間(MTA)裏面的,但是在Visual Studio裏面創建C#工程的時候,Visual Studio的項目模板會在你代碼的Main函數上加上[STAThread]屬性,表示主線程運行在STA套間裏面,這樣就會造成.NET程序有線程運行在兩個不同的套間裏面:

        [STAThread]

        public static void Main()

Main函數上面加上[STAThread]屬性會使.NET將主線程放在STA套間裏面,而加上[MTAThread]屬性則會將主線程放在MTA套間裏面。

而對於其他線程,則需要使用Thread.SetApartmentState()函數來設置線程所運行的套間,而這個函數必須在線程啓動之前調用,也就是在Thread.Start ()之前調用,這也是爲什麼.NET提供一個[STAThread]屬性和[MTAThread]屬性的原因――因爲你沒有辦法在主線程啓動之前設置主線程運行的套間。在線程裏面,你可以使用Thread.GetApartmentState()函數來獲取線程所運行的套間信息。

COM套間對.NET程序使用COM對象的影響(上)文章裏面的代碼的修復方案如下,即將主線程的STAThread屬性去掉,讓大家都運行在程序裏面唯一一個MTA套間裏面,這樣就沒有列集接口的問題了:

1. using System;

2. using System.Collections.Generic;

3. using System.Linq;

4. using System.Runtime.InteropServices;

5. using System.Text;

6. using System.Diagnostics;

7. using System.Security.Cryptography;

8. using System.Security.Principal;

9. using Microsoft.Win32.SafeHandles;

10. using System.ComponentModel;

11. using System.Reflection;

12. using System.Security;

13. using System.IO;

14. using System.Threading;

15. using System.Security.Permissions;

16.

17. using ApartmentComponentLib;

18.

19. namespace CSharpQuestions

20. {

21.     public class Watcher

22.     {

23.         private object m_IStaObject = null;

24.

25.         public static void Main()

26.         {

27.             Console.WriteLine(Thread.CurrentThread.GetApartmentState());

28.             Watcher watcher = new Watcher();

29.             watcher.Initialize();

30.             watcher.CreateThreads().Join();

31.

32.             Console.WriteLine("Press any key");

33.             Console.ReadLine();

34.         }

35.

36.         private Thread CreateThreads()

37.         {

38.             Thread thread = new Thread(ThreadFunc);

39.             thread.Start();

40.

41.             return thread;

42.         }

43.

44.         private void ThreadFunc()

45.         {

46.             Console.WriteLine(Thread.CurrentThread.GetApartmentState());

47.             IStaObject2 obj = (IStaObject2)m_IStaObject;

48.             obj.TestMethod();

49.         }

50.

51.         private void Initialize()

52.         {

53.             m_IStaObject = new StaObject2Class();

54.         }

55.     }

56. }

 

發佈了73 篇原創文章 · 獲贊 2 · 訪問量 39萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章