C#WinForms:如何设置主函数STAThreadAttribute
在后台线程中调用saveFileDialog.ShowDialog()
时出现以下exception:
在进行OLE调用之前,必须将当前线程设置为单线程单元(STA)模式。 确保您的Main函数标记了STAThreadAttribute。
根据这个 :
要解决此问题,请插入以下语句:
Threading.Thread.CurrentThread.ApartmentState = Threading.ApartmentState.STA;
在Application.Run语句之前的Main中。
但是Application.Run语句在Program.cs中,它似乎是生成的代码,因此任何更改都可能意外丢失。 此外,我找不到在项目或主窗体属性中将当前线程设置为STA的方法,但也许我在错误的地方查找。 在后台线程中调用saveFileDialog.ShowDialog()
的正确方法是什么?
不应该从后台线程调用ShowDialog() – 使用Invoke(..)。
Invoke((Action)(() => { saveFileDialog.ShowDialog() }));
解决方案很容易; 只需将其添加到Main方法[STAThread]
之上
所以你的主要方法应该是这样的
[STAThread] static void Main(string[] args) { .... }
这个对我有用。
如果您正在创建调用showDialog的线程,这应该有效:
var thread = new Thread(new ParameterizedThreadStart(param => { saveFileDialog.ShowDialog(); })); thread.SetApartmentState(ApartmentState.STA); thread.Start();
在FormLoad
上添加以下代码
private void Form1_Load(object sender, EventArgs e) { Thread myth; myth = new Thread(new System.Threading.ThreadStart(CallSaveDialog)); myth.ApartmentState = ApartmentState.STA; myth.Start(); }
这里CallSaveDialog
是一个线程,你可以在这里调用ShowDialog
void CallSaveDialog(){saveFileDialog.ShowDialog();}
在您的MainForm上:
if (this.InvokeRequired) { this.Invoke(saveFileDialog.ShowDialog()); } else { saveFileDialog.ShowDialog(); }
或者,如果您将需要从UI线程运行其他方法:
private void DoOnUIThread(MethodInvoker d) { if (this.InvokeRequired) { this.Invoke(d); } else { d(); } }
然后,调用您的方法:
DoOnUIThread(delegate() { saveFileDialog.ShowDialog(); });