locked
ThreadStateException Error in openfiledialog RRS feed

  • Question

  • I got this error in a thread that is called by my login form by this code:

            public static void ThreadProc()
            {

                Application.Run(new aplicacao());

            }
           
            private void button1_Click(object sender, EventArgs e)
            {
                if (textBox1.Text == textBox2.Text)
                {

                    System.Threading.Thread aplicacao = new System.Threading.Thread(new System.Threading.ThreadStart(ThreadProc));

                    aplicacao.Start();
                    this.Close();


                }
                else
                {
                    MessageBox.Show("Password Errada.", "Erro de Password",
                   MessageBoxButtons.OK, MessageBoxIcon.Error);
                }

            }

    In the form aplicacao that that has the openfiledialog code
    private void button1_Click_2(object sender, EventArgs e)
            {
               
                openFileDialog1.InitialDirectory = "C:\\amigisc\\fotos";
                openFileDialog1.Filter = "ficheiros jpg (*.jpg)|*.jpg";
                openFileDialog1.ShowDialog();
                string a = openFileDialog1.FileName.ToString();
                imagem.Text = a;
            }

    I have tried to put the [STAThreadAttribute] attribute in the login form but it did't work...

    Sunday, March 30, 2008 7:24 PM

Answers

  • I solve the problem with this line of code before starting the thread

    thread.SetApartmentState (ApartmentState.STA);
    Monday, March 31, 2008 2:40 PM

All replies

  •  Matrix79 wrote:
    I got this error in a thread that is called by my login form by this code:

          private void button1_Click_2(object sender, EventArgs e)
            {
               
                openFileDialog1.InitialDirectory = "C:\\amigisc\\fotos";
                openFileDialog1.Filter = "ficheiros jpg (*.jpg)|*.jpg";
                openFileDialog1.ShowDialog();
                string a = openFileDialog1.FileName.ToString();
                imagem.Text = a;
            }

    I have tried to put the [STAThreadAttribute] attribute in the login form but it did't work...

     

    What is openFileDialog1? It does not seem to be defined anywhere? I could not see it. Perhaps you posted a snippet?

     

    string a = openFileDialog1.FileName.ToString(); File name is already a string, you don't have to do it again.

     

    OpenFileDialog openFileDialog1 = new OpenFileDialog ( );

    openFileDialog1.InitialDirectory = Globals.cur_drive + @"\VCsharp_Projects\ComeAndGet\ComeAndGet\RTF Files\";

    openFileDialog1.FilterIndex = 2;

    openFileDialog1.RestoreDirectory = true;

    DialogResult res = openFileDialog1.ShowDialog ( );

     

    If the above won't work, thry to do it with no filter, just to open the directory.

    Monday, March 31, 2008 12:18 AM
  • System.Threading.ThreadStateException was unhandled
      Message="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 still getting this error when i try to open a file dialog.

    I think the problem is starting aplicacao form as thread.

    I have a login form after i login i wish to start a new form called aplicacao.If i use this.hide, if i exited the second form the application still remains in memory so i used this code to open the form aplicacao closing the login form.

    In the login form

     public static void ThreadProc()
            {

                Application.Run(new aplicacao());

            }
           
            private void button1_Click(object sender, EventArgs e)
            {
                if (textBox1.Text == textBox2.Text)
                {

                    System.Threading.Thread aplicacao = new System.Threading.Thread(new System.Threading.ThreadStart(ThreadProc));

                    aplicacao.Start();
                    this.Close();


                }
                else
                {
                    MessageBox.Show("Password Errada.", "Erro de Password",
                   MessageBoxButtons.OK, MessageBoxIcon.Error);
                }

            }

    But if the form application is started this way i can use the openfiledialog because it gives the error:


    System.Threading.ThreadStateException was unhandled
      Message="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."




    Monday, March 31, 2008 12:33 AM
  • When you are spawning this thread are you setting the ApartmentState property to sta.  Every windows application has one main thread called that has the message loop on it.  You can check the thread you are running on by looking at the boolean Application.MessageLoop property.  There is also the Application.OleRequired() method which initializes the thread, set the 2nd thread ApartmentState property to sta, and make sure you pump the message loop by calling Application.DoEvents() , some interop code to call peekmessage, translatemessage, dispatchmessage, or maybe even do a Applicaiton.Run(new FormInOtherThread()) .  I have never done this before so I do not know if it will work.  There are alot of static variables in the Applicaiton class and none of them are marked as thread static.  What is your reason for running a form in another form?  You should just try to run all your ui in the main thread.
    Monday, March 31, 2008 1:26 AM
  • The reason is a login. the user must validate before using the program(typing a password).How can i do this instead of using two forms.
    In vb6 it was easy using two forms one opens the other closed.

    form.show
    unload me

    In C#

    if i use

    form a = new form();
    a.show;
    this.close();

    It closes the the second form i opened and all of the aplication

    If i use login.hide the application still remains in memory after i exit because the login form stills in memory.

    If i start a thread i cannot use savefiledialog or openfiledialog

    In vb6 this was easy in C# its a nightmare...

    Monday, March 31, 2008 1:38 AM
  • Ok you can probably do something like this than.  Create the login form.  Run a loop and pump the message loop while the login form is open.  If the user is logged in then run the application.

        static class Program
        {
            static bool _FormClosed = false;

            /// <summary>
            /// The main entry point for the application.
            /// </summary>
            [STAThread]
            static void Main()
            {
                bool _IsLoggedIn = false;
                using (Form loginForm = new Form())
                {
                    loginForm.FormClosed +=new FormClosedEventHandler(loginForm_FormClosed);
                    loginForm.Show();
                    while (!_FormClosed)
                    {
                        Application.DoEvents();
                        Thread.Sleep(90);
                    }
                    _IsLoggedIn = loginForm.IsLoggedIn;
                }

                // If logged in start application.  otherwise exit application
                if (_IsLoggedIn)
                {
                    Application.Run(new MainForm());
                }
            }

            static void loginForm_FormClosed(object sender, FormClosedEventArgs e)
            {
                _FormClosed = true;
            }


    Monday, March 31, 2008 1:50 AM
  • or even better

        static class Program
        {
            /// <summary>
            /// The main entry point for the application.
            /// </summary>
            [STAThread]
            static void Main()
            {
                bool _IsLoggedIn = false;
                using (Form loginForm = new Form())
                {
    // If the form must set the dialog result property to ok or use some other way of checking if the user is logged in
                    if (loginForm.ShowDialog() == DialogResult.OK)
                    {
                        _IsLogged = true;
                    }
                }

                // If logged in start application.  otherwise exit application
                if (_IsLoggedIn)
                {
                    Application.Run(new MainForm());
                }
            }
        }
    Monday, March 31, 2008 1:58 AM
  • I solve the problem with this line of code before starting the thread

    thread.SetApartmentState (ApartmentState.STA);
    Monday, March 31, 2008 2:40 PM
  • I have the same problem, and it seems like you were able to solve it with thread.SetApartmentState (ApartmentState.STA); but I don't get where you placed that exactly, and where the variable thread came from, which thread?
    Wednesday, April 16, 2008 4:05 PM
  • this is my code:

    System.Threading.Thread aplicacao = new System.Threading.Thread(new System.Threading.ThreadStart(ThreadProc));
                    aplicacao.SetApartmentState( ApartmentState.STA);
                    aplicacao.Start();
                    this.Close();
    I had also put [STAThread] in program.cs right above static void Main()
    Saturday, April 26, 2008 4:03 PM
  • hello Matrix79

       i am also facing same problem of ThreadStateException

    can you clear this what is ThreadProc in your answer

    and where u write this code.

    plz reply.

    Thanks in advance

    Sarbjit

     

    Friday, May 2, 2008 8:10 AM
  • Hi All,

    After trying for couple of hrs, I got the solution



    using System.Threading;

       protected void Button1_Click(object sender, EventArgs e)
        {
            
            Thread newThread = new Thread(new ThreadStart(ThreadMethod));
            newThread.SetApartmentState(ApartmentState.STA);
            newThread.Start();     
            
        }

    static void ThreadMethod()
        {
            OpenFileDialog dlg = new OpenFileDialog();
            dlg.ShowDialog();
            MessageBox.Show(dlg.FileName);
        }
    Tuesday, July 27, 2010 6:55 PM
  • Nice! I found that the release version of my app was crashing but after I created a new thread to handle the button click, this resolved the issue.
    Monday, January 24, 2011 11:18 PM
  • hi all

    protected void Button1_Click(object sender, EventArgs e)

        {
            
            Thread newThread = new Thread(new ThreadStart(ThreadMethod));
            newThread.SetApartmentState(ApartmentState.STA);
            newThread.Start();     
            
        }

    static void ThreadMethod()
        {
            OpenFileDialog dlg = new OpenFileDialog();

            dlg.ShowDialog();

    //////////-----------------------------------

           TextBox1.Text =dlg.FileName;

    //////////-------------------------------------

        }

    I am a begainer for .net

    this code are working but openfiledialog is behind the main page and i can't assign the selection path to one text box.

    please give some solution for this problem.

    thanks.


    • Edited by sensamurai Monday, March 26, 2012 10:07 AM
    Monday, March 26, 2012 9:25 AM
  • hi all

    protected void Button1_Click(object sender, EventArgs e)

        {
            
            Thread newThread = new Thread(new ThreadStart(ThreadMethod));
            newThread.SetApartmentState(ApartmentState.STA);
            newThread.Start();     
            
        }

    static void ThreadMethod()
        {
            OpenFileDialog dlg = new OpenFileDialog();

            dlg.ShowDialog();

    //////////-----------------------------------

           TextBox1.Text =dlg.FileName;

    //////////-------------------------------------

        }

    I am a begainer for .net

    this code are working but openfiledialog is behind the main page and i can't assign the selection path to one text box.

    please give some solution for this problem.

    thanks.


    //////////-----------------------------------

           TextBox1.Text =dlg.FileName;

    //////////-------------------------------------

    are incorrect. How do I use.

    Monday, April 20, 2015 9:30 AM