2

I got some problem with thread and I need get path from folder browser dialog here is a code

Thread t = new Thread(() => myFolderBrowserDialog.ShowDialog());
                    t.IsBackground = true;
                    t.SetApartmentState(ApartmentState.STA);
                    t.Start();
Martin Janitor
  • 31
  • 1
  • 1
  • 6
  • You want to show the folder browser dialog on a non-UI thread? Strange. Are you working on a four-hand keyboard? – Simon Mourier Oct 29 '12 at 16:49
  • oh boy, you need a lot more class when writing posts here... explain clearly what you are trying to achieve, show how you are attempting to do it, and what are the technical obstacles... don't just throw mumble like this... (I don't aim to be mean.) – Fernando Espinosa Oct 29 '12 at 16:49
  • Oh my. Why would you ever want to spawn a modal dialog on the UI thread? – Patrik Svensson Oct 29 '12 at 16:52
  • For what it's worth, you *can* spawn the open file dialog in another thread as I've [answered in another question](http://stackoverflow.com/a/1174626/57787). – Joshua Oct 29 '12 at 16:57

2 Answers2

10

You could do this:

Thread t = new Thread(() => myFolderBrowserDialog.ShowDialog());
t.IsBackground = true;
t.SetApartmentState(ApartmentState.STA);
t.Start();
t.Join();

var path = myFolderBrowserDialog.SelectedPath;

But there is really zero point in the thread, it achives the same as this:

myFolderBrowserDialog.ShowDialog();  //this will block until the user presses OK or cancel.
var path = myFolderBrowserDialog.SelectedPath;

Personally, I would do this:

Using (var dialog = new FolderBrowserDialog())
{
    //setup here

    if (dialog.ShowDialog() == DialogResult.Ok)  //check for OK...they might press cancel, so don't do anything if they did.
    {
         var path = dialog.SelectedPath;    
         //do something with path
    }
}
Pondidum
  • 11,457
  • 8
  • 50
  • 69
1

I had one problem like that. The apartmentState of the main thread are [MTAThread].

At the start of the class i put these code:

public class FormWithMTA{

  delegate void ModifyTextBox(string value);
  private FolderBrowserDialog opn;
  Thread runningThread;

  ...

In the event i put this:

...
  opn = new FolderBrowserDialog();
  runningThread = new Thread(new ThreadStart(OpenDlg));
  //Change the apartmentState of that thread to work in STA if your main ApartmentState are MTA 
  runningThread.SetApartmentState(ApartmentState.STA);
  runningThread.Start();
...

and use that part of the code for get de path in the runningThread:

    private void OpenDlg()
    {
        opn.Description = "Escolha de diretório:";
        opn.ShowNewFolderButton = false;
        opn.RootFolder = System.Environment.SpecialFolder.MyComputer;

        try
        {
            DialogResult d = opn.ShowDialog();

            if (d == DialogResult.OK)
            {
                if (opn.SelectedPath != "")
                    UpdateStatus(opn.SelectedPath);
            }
        }
        catch (InvalidCastException erro)
        {
            //When work in main with MTA everytime i get that exception with dialog result
            if (opn.SelectedPath != "")
                UpdateStatus(opn.SelectedPath);
        }
        catch (Exception er)
        {
        }

        opn.Dispose();
        opn = null;

        runningThread.Join();
    }

    void UpdateStatus(string value)
    {
        if (txtBox.InvokeRequired)
        {
            //Call the delegate for this component.
            txtBox.Invoke(new ModifyTextBox(UpdateStatus), new object[] { value });
            return;
        }


        txtBox.Text = value;
    }

Well, that code work for me in windows 7 64bits. In debugger and when i execute the program in the client machine.