单元是进程内部具有相同线程访问要求的对象的逻辑容器bai。同一单元中的所有对象都可以接收从该单元中的任何线程发出的调用。.NET Framework 不使用单元,托管对象自己负责以线程安全的方式使用所有共享资源。
由于 COM 类使用单元,因此公共语言运行库需要在 COM interop 的情况下调用 COM 对象时创建并初始化一个单元。托管线程可以创建并进入只允许有一个线程的单线程单元 (STA) 或者包含一个或多个线程的多线程单元 (MTA)。通过将线程的 ApartmentState 属性设置为 ApartmentState 枚举值之一,可以控制所创建的单元的类型。由于给定线程只能初始化 COM 单元一次,因此在第一次调用非托管代码之后就不能更改单元类型。
成员定义:
STA:Thread 将创建并进入一个单线程单元。
MTA:Thread 将创建并进入一个多线程单元
Unknown:尚未设置 ApartmentState 属性。
解决办法两种:
1) 在Main入口添加STAThread的Attribute
1 [STAThread]
2 static void Main()
2)
1 Thread app = new Thread(new ParameterizedThreadStart(ShowWindow));
2 app.ApartmentState = ApartmentState.STA;
3 //也可以
4 Thread newThread = new Thread(new ThreadStart(ThreadMethod));
5 newThread.SetApartmentState(ApartmentState.MTA);
例如:
1 static void Main()
2 {
3 Thread newThread =
4 new Thread(new ThreadStart(ThreadMethod));
5 newThread.SetApartmentState(ApartmentState.MTA);
6 // The following line is ignored since
7 // ApartmentState can only be set once.
8 newThread.SetApartmentState(ApartmentState.STA);
9 Console.WriteLine("ThreadState: {0}, ApartmentState: {1}",
10 newThread.ThreadState, newThread.ApartmentState);
11 newThread.Start();
12 // Wait for newThread to start and go to sleep.
13 Thread.Sleep(300);
14 try
15 {
16 // This causes an exception since newThread is sleeping.
17 newThread.SetApartmentState(ApartmentState.STA);
18 }
19 catch(ThreadStateException stateException)
20 {
21 Console.WriteLine("
{0} caught:
" +
22 "Thread is not in the Unstarted or Running state.",
23 stateException.GetType().Name);
24 Console.WriteLine("ThreadState: {0}, ApartmentState: {1}",
25 newThread.ThreadState, newThread.GetApartmentState());
26 }
27 }
28 static void ThreadMethod()
29 {
30 Thread.Sleep(1000);
31 }