Параллельный Foreach вызывает исключение ApartmentState
У меня есть следующий код для создания вкладок в предварительно определенный список:
private void CreateControls()
{
Parallel.ForEach(_websites,
w =>
{
var tabPage = new TabPage(w.Name);
var webBrowser = new WebBrowser();
webBrowser.Navigate(w.Url);
tabPage.Controls.Add(webBrowser);
WebPagesTabControl.TabPages.Add(tabPage);
});
}
Я получаю следующее исключение:
не может быть создан, потому что текущий поток не находится в однопоточной квартире.
Как правильно установить состояние квартиры на STA?
1 ответ
Как правильно установить состояние квартиры на STA?
Вы задаете не тот вопрос.
Во-первых, вы не можете установить состояние квартиры для рабочих потоков, используемых здесь. Вы не являетесь владельцем потоков, и состояние должно быть установлено до того, как поток начнет работать.
Но, во-вторых, что более важно, даже если вы можете установить состояние, это только необходимое условие для объектов, которые вы пытаетесь создать, но не достаточное. Объекты пользовательского интерфейса должны быть не только созданы в потоке STA, они должны быть созданы в потоке STA, который имеет обработчик сообщений. Т.е. основной поток пользовательского интерфейса в вашей программе.
Если вы не хотите распространения потоков пользовательского интерфейса в своем процессе (а на самом деле вы этого не сделаете… это просто создало бы целый ряд других проблем), операция, которую вы пытаетесь выполнить, просто не поддается использованию. из Parallel.ForEach()
или любой другой метод параллелизма.
Вы должны просто использовать обычный foreach
и если есть возможность для параллелизма здесь (т. е. асинхронного выполнения HTTP-запросов), WebBrowser
Сам объект управляет этим.