Почему приложения WinForms по умолчанию являются STAThread? - PullRequest
19 голосов
/ 11 января 2011

Когда вы создаете пустое приложение WinForms в Visual Studio, шаблон имеет атрибут STAThread в основном классе приложения.

Я читал об этом несколько документов, но я не уверен, что понял вообще.

На самом деле у меня есть несколько вопросов по этому поводу:

  1. Почему этот атрибут добавлен?
  2. Что это значит?
  3. Что произойдет, если вы удалите этот атрибут?

Ответы [ 4 ]

19 голосов
/ 19 сентября 2008

Цитировать блог MSDN ,

Когда применяется атрибут STAThreadAttribute, он изменяет состояние квартиры текущего потока на однопоточное. Не вдаваясь в подробные обсуждения COM и потоков, этот атрибут обеспечивает механизм связи между текущим потоком и другими потоками, которые могут захотеть общаться с ним через COM. Когда вы используете Windows Forms, в зависимости от используемой вами функции он может использовать COM-взаимодействие для взаимодействия с компонентами операционной системы. Хорошими примерами этого являются буфер обмена и диалоги файлов.

13 голосов
/ 11 января 2011

1. Почему этот атрибут добавлен?

Поскольку это требуется объектной моделью ActiveX. Кроме того, вы можете удалить элементы управления ActiveX в WinForm (так, чтобы они были совместимы) ИЛИ некоторые классы .NET используют собственные элементы управления, которым требуется этот атрибут.

2. Что это значит?

Это означает, что поток выполняется в однопоточной модели квартиры .

3. Что произойдет, если вы удалите этот атрибут?

Если атрибут удален, поведение не определено. Программа может произойти сбой наугад, с иногда заметными сообщениями об ошибках. Например, теперь все может работать, а потом порвать с пакетом обновлений.

3 голосов
/ 09 января 2016

3.Что произойдет, если вы удалите этот атрибут?

Я просто добавляю простой пример, демонстрирующий проблему.

Я создал простое приложение WinForms с кнопкойи OpenFileDialog.По нажатию кнопки я запускаю поток, который показывает openFileDialog.Я запускаю приложение с STAThread и без него, и результаты нажатия кнопки одинаковы - оно выдает исключение «Операция с несколькими потоками недопустима: доступ к элементу управления Form1 осуществляется из потока, отличного от потока, в котором он был создан».Похоже, что нет никакой разницы.Но нет.

Затем я изменил отображение openFileDialog, вызвав следующий метод:

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

    openFileDialog1.ShowDialog(this);
}

С STAThread он работает нормально, как и ожидалось.Без STAThread он выдает исключение: «Текущий поток должен быть установлен в однопотоковый режим (STA), прежде чем могут быть выполнены вызовы OLE. Убедитесь, что в вашей функции Main помечен атрибут STAThreadAttribute. Это исключение возникает, только если к отладчику присоединенпроцесс ".

Затем я запускаю приложение несколько раз без отладчика (отдельно от visual studio).Однажды приложение просто тихо закрылось, в другой раз приложение закрылось с сообщением «vshost прекратил работать»

0 голосов
/ 19 сентября 2008

Это означает, что программы Windows Forms используют однопоточное состояние квартиры.MTA и состояния свободных многопоточных квартир не поддерживаются.

...