Поток является STA или MTA, его нельзя указать только для одного метода, поэтому атрибут должен присутствовать в точке входа.
С STAThreadAttribute
в MSDN :
Примените этот атрибут к методу точки входа (метод Main () в
C # и Visual Basic). Это не влияет на другие методы.
Если этот код вызывается из вторичного потока, у вас есть 3 варианта:
ВАЖНОЕ ПРИМЕЧАНИЕ: Выполнение (как вы, кажется, делаете) кода System.Windows.Forms внутри потока MTA неразумно, некоторые функции, такие как диалоги открытия файлов (не только папка), требуют работы потока MTA.
Изменение вашей квартиры вторичного потока
Если вы создаете тему самостоятельно (и не используете специфику MTA), вы можете просто изменить ее квартиру перед запуском:
var t = new Thread(...);
t.SetApartmentState(ApartmentState.STA);
Создание темы только для нее
Если вы не контролируете создание потока, вы можете сделать это во временном потоке:
string selectedPath;
var t = new Thread((ThreadStart)(() => {
FolderBrowserDialog fbd = new FolderBrowserDialog();
fbd.RootFolder = System.Environment.SpecialFolder.MyComputer;
fbd.ShowNewFolderButton = true;
if (fbd.ShowDialog() == DialogResult.Cancel)
return;
selectedPath = fbd.SelectedPath;
}));
t.SetApartmentState(ApartmentState.STA);
t.Start();
t.Join();
Console.WriteLine(selectedPath);
Вызов в другом (STA) потоке
Если ваш основной поток также содержит код System.Windows.Forms, который вы можете вызвать в его цикле сообщений для выполнения вашего кода:
string selectedPath = null;
Form f = // Some other form created on an STA thread;
f.Invoke(((Action)(() => {
FolderBrowserDialog fbd = new FolderBrowserDialog();
fbd.RootFolder = System.Environment.SpecialFolder.MyComputer;
fbd.ShowNewFolderButton = true;
if (fbd.ShowDialog() == DialogResult.Cancel)
return;
selectedPath = fbd.SelectedPath;
})), null);
Console.WriteLine(selectedPath);