在可以调用 OLE 之前,必须将当前线程设置为单线程单元(STA)模式
在可以调用 OLE 之前,必须将当前线程设置为单线程单元(STA)模式
转载自:http://blog.163.com/smhily_min/blog/static/75206226201092011444205/
程序之前运行正常,我只是在一个事件中定义了做了如下操作,程序抛出此异常
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();
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();
}
http://www.cnblogs.com/winzheng/archive/2008/12/02/1345656.html
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
实际上我自己在使用的时候
Thread newThread =new Thread(new ThreadStart(ThreadMethod)); newThread.SetApartmentState(ApartmentState.MTA);
用的是这个,但是还是会报错,反而使用
newThread.SetApartmentState(ApartmentState.STA);
的时候到正常运行,不知道具体的原因,仅供大家参考。
发现还有这么一篇文章页用到了这个设置的东西,有兴趣的可以看一下:
http://blog.csdn.net/xuehuic/article/details/6426284(转)
在可以调用 OLE 之前,必须将当前线程设置为单线程单元(STA)模式的更多相关文章
- 选择目录,选择文件夹的COM组件问题。在可以调用 OLE 之前,必须将当前线程设置为单线程单元(STA)模式。请确保您的 Main 函数带有 STAThreadAttribute 标记。 只有将调试器附加到该进程才会引发此异常。
异常: 在可以调用 OLE 之前,必须将当前线程设置为单线程单元(STA)模式.请确保您的 Main 函数带有 STAThreadAttribute 标记. 只有将调试器附加到该进程才会引发此异常. ...
- c# Clipboard.SetDataObject(bmp1) 在可以调用 OLE 之前,必须将当前线程设置为单线程单元(STA)模式。请确保您的 Main 函数带有 STAThreadAttribute 标记。 只有将调试器附加到该进程才会引发此异常
c# Clipboard.SetDataObject(bmp1) 在可以调用 OLE 之前,必须将当前线程设置为单线程单元(STA)模式.请确保您的 Main 函数带有 STAThreadAttri ...
- 异常错误:在可以调用 OLE 之前,必须将当前线程设置为单线程单元(STA)模式
最近做一个蛋疼的东西就是C#调用windows API 来操作一个摄像头,自动处理一些东西.要用到剪切板复制 粘贴功能,即 Clipboard.SetDataObject(filedic, true) ...
- 在可以调用OLE之前,必须将当前线程设置为单线程单元(STA)模式,请确保您的Main函数带有STAThreadAttribute
导入导出功能,在调用ShowDialog时的错误,解决办法如下: WinForm窗体的入口点: /// <summary> /// 应用程序的主入口点. /// </summary& ...
- C#“必须先将当前线程设置为单个线程单元(STA)模式方可进行OLE调用”异常解决方案
关于这类问题网上搜索会有很多解决方案,但基本的意思都相差不大,大致问题出于启用线程时调用类似剪贴板Clipboard.SetDataObject出错,我把我的测试代码展现下: 解决方案:只需将thre ...
- Current thread must be set to single thread apartment (STA) mode before OLE,当前线程不在单线程单元中,因此无法实例化 ActiveX 控件“8856f961-340a-11d0-a96b-00c04fd705a2”。
Add the STAThreadAttribute attribute on the Main method. This attribute is required if your program ...
- .net winform 调用类中的webbrowser 报错:当前线程不在单线程单元中,因此无法实例化 ActiveX
遇到这个恶心的问题纠缠得不要不要的,大家遇到了的话希望不要走弯路,经过这个折腾让我有点怀疑人生了.哈哈哈 解决代码如下: //插入一个新线程用于处理验证码 Thread thd = new Threa ...
- 类中调用界面ActiveX控件报错当前线程不在单线程单元中因此无法实例化 ActiveX 控件的解决办法
解决办法是Form类中定义一个静态的ActiveX对象,在formload中将界面上的ActiveX对象赋值给新定义的对象,类中访问该静态对象即可. public static AxClientDri ...
- 每次调用fork()函数之后,父线程和创建出的子线程都是从fork()后开始执行
Linux下多少个"-"将被打印: 1 2 3 4 5 6 7 8 int main(void){ int i; for(i=0;i<4;i++){ fork() ...
随机推荐
- 从零开始学Python第0周:Python基本介绍(部分内容来源于网络)
Python入门介绍 一,Python的基本介绍 (1)概要 Python是一种解释型,面向对象,动态数据类型的高级程序设计语言.常被广泛用于处理系统管理任务和web编程.现如今Python已经成为了 ...
- CI框架源码阅读笔记1 - 环境准备、基本术语和框架流程
最开始使用CI框架的时候,就打算写一个CI源码阅读的笔记系列,可惜虎头蛇尾,一直没有行动.最近项目少,总算是有了一些时间去写一些东西.于是准备将之前的一些笔记和经验记录下来,一方面权作备忘,另一方面时 ...
- Python自动化测试工具Splinter简介和使用实例
Splinter 快速介绍 官方网站:http://splinter.cobrateam.info/ 官方介绍: Splinter is an open source tool for testing ...
- Java空白final
Java 1.1允许我们创建"空白final",它们属于一些特殊的字段.尽管被申明为final,但却未得到一个初始值. 无论在哪种情况下,空白final都必须在实际使用前得到正确的 ...
- php 相关模块备忘
在安装php的时候,不管是编译安装: ./configure --prefix=/usr/local/php --with-config-file-path=/usr/local/php/etc -- ...
- Community Value再理解
其实之前写“从香港机房引入google/bitbucket路由”的时候,对community value的了解还并不深入,对Juniper default BGP export/import poli ...
- CSS3中DIV水平垂直居中-2(3)
用到CSS3中display的新属性. HTML <div class="parent"> </div> CSS html,body{ width: 100 ...
- NodeJS API简介
简单介绍下NodeJS现有API. Assert(断言):该模块用于编写程序的单元测试用例. Buffer(缓冲块) :处理二进制数据. C/C++ Addons(拓展):Addons插件就是动态连接 ...
- [Android]RapidFloatingActionButton框架正式出炉
以下内容为原创,欢迎转载,转载请注明 来自天天博客:http://www.cnblogs.com/tiantianbyconan/p/4474748.html RapidFloatingActionB ...
- Android studio 使用SVN需要忽略的文件
Android Studio创建的Android项目一般需要忽略 1..idea文件夹 2..gradle文件夹 3.所有的build文件夹 4.所有的.iml文件 5.local.propertie ...