Dan*_*iel 22 c# multithreading exception folderbrowserdialog
尝试使用FolderBrowserDialog时,我收到以下异常:
System.Threading.ThreadStateException: Current thread must be set to single thread apartment (STA) mode before OLE calls can be made. Ensure that your Main function has STAThreadAttribute marked on it. This exception is only raised if a debugger is attached to the process.
我已经广泛搜索了这个问题,并且每个人都建议的解决方案似乎是放在[STAThreadAttribute]Main方法之上,从Debug文件夹中删除所有dll,或者使用该Invoke方法.我已经尝试了所有这些,我仍然得到相同的例外.
这是代码:
public partial class Form1 : Form
{
public event EventHandler ChooseLocationHandler = null;
public string DestFolder
{
set { textBox1.Text = value; }
get { return textBox1.Text; }
}
public Form1()
{
InitializeComponent();
}
private void ChooseLocationButton_Click(object sender, EventArgs e)
{
if (ChooseLocationHandler != null)
ChooseLocationHandler(this, e);
}
}
Run Code Online (Sandbox Code Playgroud)
我的演示者如下:
public partial class Presenter
{
Form1 myForm;
public Presenter()
{
myForm = new Form1();
myForm.ChooseLocationHandler += ChooseLocationHandler;
myForm.Show();
}
public void ChooseLocationHandler(object obj, EventArgs e)
{
Form1 sender = (Form1)obj;
FolderBrowserDialog fbd = new FolderBrowserDialog();
fbd.RootFolder = System.Environment.SpecialFolder.MyComputer;
fbd.ShowNewFolderButton = true;
if (fbd.ShowDialog() == DialogResult.Cancel)
return;
sender.DestFolder = fbd.SelectedPath;
}
}
Run Code Online (Sandbox Code Playgroud)
我在fbd.ShowDialog()上得到了Exception.
Jul*_*lia 52
线程是STA或MTA,不能仅为一个方法指定,因此该属性必须出现在入口点上.
将此属性应用于入口点方法(C#和Visual Basic中的Main()方法).它对其他方法没有影响.
如果从辅助线程调用此代码,您有3个选择:
重要说明:运行(如您所愿)MTA线程内的System.Windows.Forms代码是不明智的,一些功能如文件打开对话框(不仅是文件夹)需要MTA线程才能工作.
如果您自己创建线程(并且不使用MTA的特性),您可以在启动之前更改它的公寓:
var t = new Thread(...);
t.SetApartmentState(ApartmentState.STA);
Run Code Online (Sandbox Code Playgroud)
如果您不控制线程创建,您可以在临时线程中执行此操作:
string selectedPath;
var t = new Thread((ThreadStart)(() => {
FolderBrowserDialog fbd = new FolderBrowserDialog();
fbd.RootFolder = System.Environment.SpecialFolder.MyComputer;
fbd.ShowNewFolderButton = true;
if (fbd.ShowDialog() == DialogResult.Cancel)
return;
selectedPath = fbd.SelectedPath;
}));
t.SetApartmentState(ApartmentState.STA);
t.Start();
t.Join();
Console.WriteLine(selectedPath);
Run Code Online (Sandbox Code Playgroud)
如果您的主线程还包含System.Windows.Forms代码,您可以在其消息循环中调用以执行您的代码:
string selectedPath = null;
Form f = // Some other form created on an STA thread;
f.Invoke(((Action)(() => {
FolderBrowserDialog fbd = new FolderBrowserDialog();
fbd.RootFolder = System.Environment.SpecialFolder.MyComputer;
fbd.ShowNewFolderButton = true;
if (fbd.ShowDialog() == DialogResult.Cancel)
return;
selectedPath = fbd.SelectedPath;
})), null);
Console.WriteLine(selectedPath);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
27137 次 |
| 最近记录: |