在可以调用 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() ...
随机推荐
- [moka同学笔记]Yii2 数据操作Query Builder
Query Builder [php] view plain copy $rows = (new \yii\db\Query()) ->select(['dyn_id', 'dyn_name ...
- Mac OS Git 安装
一.Git是一个分布式的代码版本管理工具.类似的常用工具还有SVN,CVS.最大的特点也是优点在于提供分布式的代码管理 1.分支代码只有一份! 使用过svn的童鞋想必都知道,当我们要开发一个新功能或者 ...
- 高效 Java Web 应用开发框架 JessMA v3.2.2 正式发布
JessMA(原名:Portal-Basic)是由 JessMA Open Source 开发的一套高效 Java Full-Stack Web 应用开发框架,内置可扩展的 MVC Web 基础架构和 ...
- mysql 5.7.17发布
Mysql 5.7.17发布了,主要修复: Changes in MySQL 5.7.17 (2016-12-12, General Availability) Compilation Notes M ...
- C#多线程:使用ReaderWriterLock类实现多用户读/单用户写同步
摘要:C#提供了System.Threading.ReaderWriterLock类以适应多用户读/单用户写的场景.该类可实现以下功能:如果资源未被写操作锁定,那么任何线程都可对该资源进行读操作锁定, ...
- display---我的第一篇博客
display:block显示为块级元素,换行 display:inline-block显示为块级内联元素,不换行,但是可以改变其宽度高度 display:inline显示为内联元素,不换行但是也不能 ...
- Scroll Depth – 衡量页面滚动的 Google 分析插件
Scroll Depth 是一个小型的 Google Analytics(谷歌分析)插件,可以让你衡量用户在页面上滚动了多远.它可以监控 25%.50%.75% 和 100% 四个滚动点,并发送谷歌分 ...
- div水平居中
1.先给它外层的div定位并left:position:absolute;left:50%; 2.获取当前元素div的宽度,并除以2 3.改变它的css:margin-left:-(获取当前元素div ...
- ABAP 锁机制
- 为Autodesk Viewer添加自定义工具条
如果你参加过我们近期的活动,你就会频繁的听到我们现在正在做的Autodesk Viewer大模型浏览器,这是一个不需要下载任何插件,基于WebGL技术的浏览器,可以支持几十种数据格式.同时viewer ...