使用FolderBrowserDialog时发生异常 [英] Exception when using FolderBrowserDialog

查看:546
本文介绍了使用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.

I'm getting the following Exception when trying to use 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方法.我已经尝试了所有这些方法,但仍然遇到相同的异常.

I have Googled this problem extensively and the solutions that everybody suggests seem to be to put [STAThreadAttribute] above the Main method, to delete all dll's from the Debug folder, or to use the Invoke method. I have tried all of these, and I still get the same exception.

代码如下:

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);
    }
}

在我的演示者中是:

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;
    }
}

我在fbd.ShowDialog()上遇到异常.

I'm getting the Exception on fbd.ShowDialog().

推荐答案

线程是STA还是MTA,不能仅为一种方法指定线程,因此属性必须出现在入口点.

A thread is either STA or MTA it can't be specified just for one method so the attribute must be present on the entry point.

从MSDN中的 STAThreadAttribute

将此属性应用于入口点方法( C#和Visual Basic).它对其他方法没有影响.

Apply this attribute to the entry point method (the Main() method in C# and Visual Basic). It has no effect on other methods.

如果从辅助线程调用此代码,则有3种选择:

If this code is called from a secondary thread you have 3 choices :

重要说明:在MTA线程中运行(如您所愿)System.Windows.Forms代码是不明智的,文件打开对话框(不仅是文件夹)之类的某些功能需要MTA线程才能工作.

如果您自己创建线程(并且不使用MTA的特殊性),则可以在启动它之前更改它的单元:

If you create the thread yourself (and don't use the specificity of MTA) you could just change it's apartment before starting it :

var t = new Thread(...);
t.SetApartmentState(ApartmentState.STA);

 

如果您不控制线程的创建,则可以在临时线程中进行操作:

If you don't control the thread creation you could do it in a temporary thread :

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);

 

如果您的主线程还包含System.Windows.Forms代码,则可以在其消息循环中调用它来执行代码:

If your main thread also contain System.Windows.Forms code you could invoke in it's message loop to execute your code :

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);

这篇关于使用FolderBrowserDialog时发生异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆