Использование GeckoFX в многопоточном приложении - PullRequest
1 голос
/ 30 марта 2011

У меня возникают проблемы с пониманием того, как именно обрабатывать потоки при использовании GeckoFX - похоже, он постоянно выдает ошибки при попытке использовать GeckoWebBrowser в других потоках.

В частности, в этом тестовом приложении я пытаюсь создать миниатюру веб-страницы и отобразить ее в форме (а не в самом элементе управления WebBrowser). При работе в однопоточном режиме прекрасно работает:

private void browser_DocumentCompleted(object sender, EventArgs e)
{
    GeckoWebBrowser browser = sender as GeckoWebBrowser;
    if (browser.Url.ToString() != "about:blank")
    {
        webBrowserReady = true;
    }
}

private void btnGo_Click(object sender, EventArgs e)
{
    Xpcom.Initialize();

    GeckoWebBrowser browser = new GeckoWebBrowser();
    browser.Width = 1600;
    browser.Height = 1200;
    browser.DocumentCompleted += new EventHandler(browser_DocumentCompleted);
    webBrowserReady = false;        
    browser.CreateControl();
    browser.Navigate(txtUrl.Text);

    while (!webBrowserReady)
        Application.DoEvents();

    if (webBrowserReady)
        DrawWebBrowserToImage(browser);

    browser.Dispose();
}

Однако, если я перемещаю создание и рендеринг браузера в собственный поток, я получаю сообщение об ошибке COM, когда пытаюсь вызвать CreateControl ():

Xpcom.Initialize();
Thread t = new Thread(new ThreadStart(()=>{
    GeckoWebBrowser browser = new GeckoWebBrowser();
    /* all the rest of the gecko stuff here too */
}
t.Start();

Чтобы это исправить, я также могу переместить вызов Xpcom.Initialize в поток:

Thread t = new Thread(new ThreadStart(()=>{
    Xpcom.Initialize();
    GeckoWebBrowser browser = new GeckoWebBrowser();
    /* all the rest of the gecko stuff here too */
}
t.Start();

Это прекрасно работает ... один раз. Во второй раз, когда я пытаюсь перейти, DocumentCompleted будет запущен только один раз (с about: blank). Через некоторое время также появится сообщение об ошибке COM. Мне кажется, это указывает на то, что вызов Xpcom.Initialize (статический метод, который можно вызывать только для одного приложения и ничего не делать каждый последующий раз) постоянно связывает GeckoFX с этим конкретным потоком. Навсегда.

Есть ли способ заставить Xpcom и GeckoFX правильно работать в многопоточной среде?

Ответы [ 2 ]

0 голосов
/ 18 апреля 2014
GeckoFx can only be called from the same thread on which it was initialized (normally the UI thread)

поэтому, если вы хотите вызвать GeckoFx Control, метод должен исходить из потока, который инициализировал GeckoFx Control, обычно его потока пользовательского интерфейса, как в вашем случае.Вы можете использовать BeginInvoke в Form классе, попробуйте так:

        this.BeginInvoke(new Action(() =>
        {
           browser.Navigate(txtUrl.Text);
            //your code
        }));
0 голосов
/ 09 декабря 2011

Это решит вашу проблему, поставьте ее в конце вашего запроса навигации:

myGeckoFxBrowser.Navigate("about:blank");
myGeckoFxBrowser.Document.Cookie = "";
myGeckoFxBrowser.Stop();
...