Why are WinForms applications STAThread by default

2020-01-29 15:09发布

When you create an empty WinForms application with Visual Studio, the template has the STAThread attribute in the main application class.

I have been reading some docs about it, but I'm not sure if I understood it at all.

Really I have some questions about it:

  1. Why is this attribute added?
  2. What does it mean?
  3. What happens if you remove this attribute?

4条回答
ゆ 、 Hurt°
2楼-- · 2020-01-29 15:28

To quote from an MSDN blog,

When the STAThreadAttribute is applied, it changes the apartment state of the current thread to be single threaded. Without getting into a huge discussion about COM and threading, this attribute ensures the communication mechanism between the current thread and other threads that may want to talk to it via COM. When you're using Windows Forms, depending on the feature you're using, it may be using COM interop in order to communicate with operating system components. Good examples of this are the Clipboard and the File Dialogs.

查看更多
女痞
3楼-- · 2020-01-29 15:29

1. Why is this attribute added?

Because it is required by the ActiveX object model. And you can drop ActiveX controls on a WinForm (so it is there for compatibility) OR some .NET classes use native controls which require that attribute.

2. What does it mean?

It means the thread runs in the single-threaded apartment model.

3. What happens if you remove this attribute?

If the attribute is removed, the behavior is undefined. The program may fail at random, with sometimes sensible error messages. For example, things may work now, then break with a service pack.

查看更多
孤傲高冷的网名
4楼-- · 2020-01-29 15:35

It means that Windows Forms programs use a single-threaded apartment state. MTA and free threaded apartment states are not supported.

查看更多
Explosion°爆炸
5楼-- · 2020-01-29 15:43

3.What happens if you remove this attribute?

I just add a simple example which demonstrates the problem.

I created simple WinForms app with a button and an OpenFileDialog. On button click I run a thread which shows the openFileDialog. I launch the app with and without STAThread and results of clicking the button are the same - it throws the exception "Cross-thread operation not valid: Control 'Form1' accessed from a thread other than the thread it was created on". It looks as if there is no difference. But no.

Then I changed showing the openFileDialog by calling the method below:

private void ShowOFD()
{
    if (InvokeRequired)
    {
        BeginInvoke(new Action(ShowOFD));
        return;
    }

    openFileDialog1.ShowDialog(this);
}

With STAThread it works fine as expected. Without STAThread it throws the exception: "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".

Then I launch the app several times without debugger (detached from visual studio). One time the app just silently closed, another time the app closed with the message "vshost has stopped working"

查看更多
登录 后发表回答