C#WinForms:如何设置主函数属性
在后台线程中调用C#WinForms:如何设置主函数属性,c#,winforms,C#,Winforms,在后台线程中调用saveFileDialog.ShowDialog()时,出现以下异常: 当前线程必须设置为单线程 OLE之前的线程单元(STA)模式 可以打电话。确保您的 Main函数具有stathreadsattribute属性 上面有记号 根据: 要解决此问题,请插入 声明: 主要是在 运行语句 但是Application.Run语句位于Program.cs中,它似乎是由代码生成的,因此任何更改都可能意外丢失。此外,我找不到在项目或主窗体属性中将当前线程设置为STA的方法,但可能我找错了位
saveFileDialog.ShowDialog()
时,出现以下异常:
当前线程必须设置为单线程
OLE之前的线程单元(STA)模式
可以打电话。确保您的
Main函数具有stathreadsattribute属性
上面有记号
根据:
要解决此问题,请插入
声明:
主要是在
运行语句
但是Application.Run语句位于Program.cs中,它似乎是由代码生成的,因此任何更改都可能意外丢失。此外,我找不到在项目或主窗体属性中将当前线程设置为STA的方法,但可能我找错了位置。
在后台线程中调用saveFileDialog.ShowDialog()
的正确方法是什么?ShowDialog()不应从后台线程调用-使用Invoke(…)
如果您正在创建调用showDialog的线程,则此操作应该有效:
var thread = new Thread(new ParameterizedThreadStart(param => { saveFileDialog.ShowDialog(); }));
thread.SetApartmentState(ApartmentState.STA);
thread.Start();
在主窗体上:
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();
});
解决方案非常简单;
只需将此添加到主方法的顶部[STAThread]
所以你的主要方法应该是这样的
[STAThread]
static void Main(string[] args)
{
....
}
void CallSaveDialog(){saveFileDialog.ShowDialog();}
它适合我。在
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
[STAThread]
static void Main(string[] args)
{
....
}
void CallSaveDialog(){saveFileDialog.ShowDialog();}
Program.cs由向导创建,但从未重新生成(与*.Designer.cs等不同,您的更改实际上会丢失)。+1,只有一个解决方案对我有效(从my.dll中的另一个线程调用
ShowDialog()
)。谢谢。你能解释一下这是怎么回事吗?