Однопоточная квартира - не может создать экземпляр элемента управления ActiveX - PullRequest
60 голосов
/ 13 сентября 2009

Мне нужно получить информацию о применяемых стилях CSS на странице HTML. Я использовал AxWebBrowser и перебрал IHTMLDOMNode. Я могу получить все необходимые данные и переместить код в свое приложение. Проблема в том, что эта часть выполняется внутри фонового рабочего, и я получил исключение при попытке создать экземпляр элемента управления.

AxWebBrowser browser = new AxWebBrowser();

ActiveX control '8856f961-340a-11d0-a96b-00c04fd705a2' cannot be instantiated
because the current thread is not in a single-threaded apartment.

Есть ли способ решить эту или иную опцию, кроме AxWebBrowser?

Ответы [ 3 ]

77 голосов
/ 13 сентября 2009

Проблема, с которой вы сталкиваетесь, заключается в том, что большинство API фоновых потоков / рабочих потоков создают поток в состоянии многопоточной квартиры. Сообщение об ошибке указывает на то, что для элемента управления требуется, чтобы поток представлял собой однопотоковую квартиру.

Вы можете обойти это, самостоятельно создав поток и указав состояние квартиры STA в потоке.

var t = new Thread(MyThreadStartMethod);
t.SetApartmentState(ApartmentState.STA);
t.Start();
60 голосов
/ 21 мая 2011

Идите вперед и добавьте [STAThread] в основную запись вашего приложения, это указывает на то, что модель потоков COM является однопоточным (STA)

пример:

static class Program
{
    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    [STAThread]
    static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new WebBrowser());
    }
}
4 голосов
/ 12 декабря 2014

Если вы использовали [STAThread] для основной записи вашего приложения и по-прежнему получаете сообщение об ошибке, вам может потребоваться сделать Потоково-безопасный вызов для элемента управления ... примерно так, как показано ниже. В моем случае с той же проблемой сработало следующее решение!

Private void YourFunc(..)
{
    if (this.InvokeRequired)
    {
        Invoke(new MethodInvoker(delegate()
        {
           // Call your method YourFunc(..);
        }));
    }
    else
    {
        ///
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...