-1

I just am changing a GUI application from STAThread to MTAThread as it does some parallel background work. Now I encountered the issue of accessing the Clipboard from within a MTAThread application.

I tried to create a dedicated STA thread on my own, failed, then tried this class https://stackoverflow.com/a/21684059/2477582 and failed again.

From dot net framework source code I found that Application.OleRequired() not matching ApartmentState.STA is the only condition to raise ThreadStateException. But this matches for my implementation, while the exception is raised nevertheless!

Tests without VS debugger let me proceed the application from this ".NET encountered an unhandled exception" dialog and then the Clipboard contains the correct value! So it works, but I have no chance to catch the exception, as it raises from some unidentifyable thread void directly into Application.Run(new MyMainform()).

Am I doing something wrong or has .NET behaviour changed here?

Program.cs:

    [MTAThread]
    static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);

        try
        {
            Application.Run(new ds_Main());
        }
        catch (System.Threading.ThreadStateException ex)
        {
            // It always falls out here
            System.Diagnostics.Debug.WriteLine("ThreadStateException: " + ex.ToString());
        }
    }

ds_Main.cs, DataGridView KeyDown handler:

private void ds_ImportTableView_KeyDown(object sender, KeyEventArgs e)
{
    if (e.Control && e.KeyCode == Keys.C)
    {
        string ll_CopyString = "foobar";    // some other stuff is here of course...

        try
        {
            Thread l_StaThread = new Thread(() =>
                {
                    // this prints: STA=?STA
                    System.Diagnostics.Debug.WriteLine(Application.OleRequired().ToString() + "=?" + System.Threading.ApartmentState.STA.ToString());

                    try
                    {
                        Clipboard.SetDataObject(ll_CopyString);
                    }
                    catch (Exception ex)
                    {
                        // It never catches here ...
                        System.Diagnostics.Debug.WriteLine("Exception in STA Delegate: " + ex.Message);
                    }
                });

            l_StaThread.SetApartmentState(ApartmentState.STA);
            l_StaThread.Start();
        }
        catch (Exception ex)
        {
            // It doesn't catch here either ...
            System.Diagnostics.Debug.WriteLine("Exception in STA Thread: " + ex.ToString());
        }
    }
}
Community
  • 1
  • 1
Nicolas
  • 754
  • 8
  • 22
  • 1
    Programmers never know how to do this correctly. You don't either, that STA thread you created is *drastically* wrong. You got lucky and got the framework to step in, denying your right to make code you did not write randomly crash or deadlock. That was just blind luck, you can't depend on it. The entrypoint of a UI thread of a program **must** be [STAThread], no shortcuts. – Hans Passant Jul 27 '15 at 12:01
  • Well ... thank you for your comment, but I am not sure if it is of any help to me. Given the fact, that the [STAThread] and [MTAThread] attributes exist, one has to conclude that the intention for their existence is to be able to use them. Also, I didn't asked for an answer to the heavily emotionally polluted question of whether to use MTA or not. Instead, I asked why my implementation of the referred solutions don't work for me. If you feel the necessity to discuss the validity of those solutions, I would ask you to do this there and not here. Thank you for your understanding. – Nicolas Jul 27 '15 at 12:09
  • http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem – Hans Passant Jul 27 '15 at 12:12
  • I don't see why this should apply, as I described the broader picture, but you did not provided an alternative to fulfill it. Instead, you disgraced me personally, which - in no situation ever possible - is/will be a legitimate approach. I ask you again to either start providing help, or stop commenting my question. If you don't like it, you are not forced to comment/answer it. Thank you. – Nicolas Jul 27 '15 at 16:41

1 Answers1

-1

While I still don't know the correct answer of this question, I announce that there is no need to answer it anymore.

This is because I found out that multithreading do work in STAThread attributed UI applications as well.

To identify this, I made synthetic tests, that proved the parallel execution while interacting/invoking with the UI as it was implemented always in my application. The reason for me to try the MTAThread attribute was an external library not behaving as expected, giving the impression of overall single threaded execution throughout the UI application.

For anyone, wondering about similar issues, I have deep understanding for your confusion regarding this topic. But I advise, to first make synthetic tests prior to asking a question out here, as there seems little tolerance for errors in reasoning.

Nicolas
  • 754
  • 8
  • 22