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. }

 

你可能感兴趣的:(thread,.net,object,C#,System,Class)