【转】在可以调用 OLE 之前,必须将当前线程设置为单线程单元(STA)模式
在可以调用 OLE 之前,必须将当前线程设置为单线程单元(STA)模式。请确保您的 Main 函数带有 STAThreadAttribute 标记。 只有将调试器附加到该进程才会引发此异常。 程序之前运行正常,我只是在一个事件中定义了做了如下操作,程序抛出此异常 private void OnExportPlan(object sender, EventArgs e) { try { if (null != ExportPlan) { Cursor = Cursors.WaitCursor; saveFileDialog1.Filter = "(Excel2003).xls|*.xls|(Excel2007).xlsx|*.xlsx"; if (DialogResult.OK == saveFileDialog1.ShowDialog()) { mExportFilePath = saveFileDialog1.FileName; Application.DoEvents(); ExportPlan(this, null); } } } finally { Cursor = Cursors.Default; } } 查看MSDN,有如下说明: 单元是进程内部具有相同线程访问要求的对象的逻辑容器。同一单元中的所有对象都可以接收从该单元中的任何线程发出的调用。.NET Framework 不使用单元,托管对象自己负责以线程安全的方式使用所有共享资源。 由于 COM 类使用单元,因此公共语言运行库需要在 COM interop 的情况下调用 COM 对象时创建并初始化一个单元。托管线程可以创建并进入只允许有一个线程的单线程单元 (STA) 或者包含一个或多个线程的多线程单元 (MTA)。通过将线程的 ApartmentState 属性设置为 ApartmentState 枚举值之一,可以控制所创建的单元的类型。由于给定线程只能初始化 COM 单元一次,因此在第一次调用非托管代码之后就不能更改单元类型。 成员定义: STA:Thread 将创建并进入一个单线程单元。 MTA:Thread 将创建并进入一个多线程单元 Unknown:尚未设置 ApartmentState 属性。 解决办法两种: 1) 在Main入口添加STAThread的Attribute [STAThread] static void Main() 2) Thread app = new Thread(new ParameterizedThreadStart(ShowWindow)); app.ApartmentState = ApartmentState.STA; //也可以 Thread newThread = new Thread(new ThreadStart(ThreadMethod)); newThread.SetApartmentState(ApartmentState.MTA); 转载请注明原创地址:http://www.cnblogs.com/winzheng/archive/2008/12/02/1345656.html 例如: static void Main() { Thread newThread = new Thread(new ThreadStart(ThreadMethod)); newThread.SetApartmentState(ApartmentState.MTA); // The following line is ignored since // ApartmentState can only be set once. newThread.SetApartmentState(ApartmentState.STA); Console.WriteLine("ThreadState: {0}, ApartmentState: {1}", newThread.ThreadState, newThread.ApartmentState); newThread.Start(); // Wait for newThread to start and go to sleep. Thread.Sleep(300); try { // This causes an exception since newThread is sleeping. newThread.SetApartmentState(ApartmentState.STA); } catch(ThreadStateException stateException) { Console.WriteLine("\n{0} caught:\n" + "Thread is not in the Unstarted or Running state.", stateException.GetType().Name); Console.WriteLine("ThreadState: {0}, ApartmentState: {1}", newThread.ThreadState, newThread.GetApartmentState()); } } static void ThreadMethod() { Thread.Sleep(1000); } http://www.cnblogs.com/winzheng/archive/2008/12/02/1345656.html
==================================原文链接===此文章由博客转发小工具转发==================================
- 学习本是一个不断抄袭、模仿、练习、创新的过程。
- 虽然,园中已有本人无法超越的同主题博文,为什么还是要写。
- 对于自己,博文只是总结。在总结的过程发现问题,解决问题。
- 对于他人,在此过程如果还能附带帮助他人,那就再好不过了。
- 由于博主能力有限,文中可能存在描述不正确,欢迎指正、补充!
- 感谢您的阅读。如果文章对您有用,那么请轻轻点个赞,以资鼓励。
- 工控物联Q群:995475200
浙公网安备 33010602011771号