Thread\Threading.Timer\Task中ShowDialog()方法报错:“在可以调用 OLE 之前,必须将当前线程设置为单线程单元(STA)模式”
在可以调用 OLE 之前,必须将当前线程设置为单线程单元(STA)模式。请确保您的 Main 函数带有 STAThreadAttribute 标记。
出错环境:
1、在Thread线程中,调用ShowDialog()方法
2、在线程定时器中,调用ShowDialog()方法
3、在Task任务中调用ShowDialog()方法
出错异常:
当执行到.ShowDialog()方法的时候,就会出现如下错误提示:“在可以调用 OLE 之前,必须将当前线程设置为单线程单元(STA)模式,请确保您的Main函数带有STAThreadAttribute标记。”
出错原因:
1、首先先确认一下程序主入口是否有STAThreadAttribute标记,如果没有请加上[STAThread]查看问题是否解决
2、由于该操作在新创建的线程中执行,是不能访问UI的,也就是直接调用ShowDialog()方法确实是有问题的。非UI线程不能打开窗口
解决方案:
1、Thread 线程
通过将线程的 ApartmentState 属性设置为ApartmentState 枚举值之一,可以控制所创建的单元的类型。
其中:
STA:Thread 将创建并进入一个单线程单元;
MTA:Thread 将创建并进入一个多线程单元;
Unknown:尚未设置 ApartmentState 属性。
代码如下:
Thread th = new Thread(()=> new Form1().ShowDialog()); th.SetApartmentState(ApartmentState.STA); th.Start();
这是网上常用的做法
2、System.Threading.Timer 线程定时器
见下文!!
3、Task 任务
Task封装的是任务,是工作内容,不是线程。一个Task可能在任何线程上执行,所以Task不会提供线程属性,也不该在异步方法中使用Thread类,更不应该在Task里面修改线程的ApartmentState属性,因为这个线程可能会执行其他的Task。亦或者说STA 线程不能是线程池线程!! 见下文!!
因此!!大招在此!!!
👉多线程访问界面应该使用Control.Invoke委托让UI线程自己做👈
this.Invoke(some delegate);//同步
or
this.BeginInvoke(some delegate);//异步
代码如下:
private void button1_Click(object sender, EventArgs e) { Func<string> func = OFD; Task task = new Task(() => { string res = (string)this.Invoke(func);//同步!让UI线程自己做 }); task.Start(); } private string OFD() { OpenFileDialog dlg = new OpenFileDialog(); if (dlg.ShowDialog() == DialogResult.OK) { string path = dlg.FileName; return path; } return null; }
作者:x1angzeeD.
转载请注明出处,感谢阅读!欢迎一起讨论!!
- 在可以调用 OLE 之前,必须将当前线程设置为单线程单元(STA)模式,请确保您的Main函数带有STAThreadAttribute标记。 多线程操作剪切板的时候。
- 在可以调用 OLE 之前,必须将当前线程设置为单线程单元(STA)模式
- 遇到的问题-----------c#在可以调用 OLE 之前,必须将当前线程设置为单线程单元(STA)模式
- 其他信息:在可以调用OLE之前,必须将当前线程设置为单线程单元(STA)模式
- 在可以调用OLE之前,必须将当前线程设置为单线程单元(STA)模式,请确保您的Main函数带有STAThreadAttribute...
- 在可以调用 OLE 之前,必须将当前线程设置为单线程单元(STA)模式
- 在可以调用 OLE 之前,必须将当前线程设置为单线程单元(STA)模式
- 在可以调用 OLE 之前,必须将当前线程设置为单线程单元(STA)模式
- 在可以调用 OLE 之前,必须将当前线程设置为单线程单元(STA)模式
- 在可以调用 OLE 之前,必须将当前线程设置为单线程单元(STA)模式,请确保您的Main函数带有STAThreadAttribute标记。
- 在可以调用 OLE 之前,必须将当前线程设置为单线程单元(STA)模式。请确保您的 Main 函数带有 STAThreadAttribute 标记。 只有将调试器附加到该进程才会引发此异常
- 选择目录,选择文件夹的COM组件问题。在可以调用 OLE 之前,必须将当前线程设置为单线程单元(STA)模式。请确保您的 Main 函数带有 STAThreadAttribute 标记。 只有将调试器附加到该进程才会引发此异常。
- ex = {"在可以调用 OLE 之前,必须将当前线程设置为单线程单元(STA)模式。 解决办法
- 在可以调用 OLE 之前,必须将当前线程设置为单线程单元(STA)模式。请确保您的 Main 函数带有 STAThreadAttribute 标记。 只有将调试器附加到该进程才会引发此异常
- 在可以调用 OLE 之前,必须将当前线程设置为单线程单元(STA)模式。请确保您的 Main 函数带有 STAThreadAttr...
- 在可以调用 OLE 之前,必须将当前线程设置为单线程单元(STA)模式
- 在可以调用 OLE 之前,必须将当前线程设置为单线程单元(STA)模式
- (转)在可以调用 OLE 之前,必须将当前线程设置为单线程单元(STA)模式,请确保您的Main函数带有STAThreadAttribute标记。
- 遇到的问题-----------c#在可以调用 OLE 之前,必须将当前线程设置为单线程单元(STA)模式
- 在可以调用 OLE 之前,必须将当前线程设置为单线程单元(STA)模式。请确保您的 Main 函数带有 STAThreadAttr