2011-03-30 4 views
1

Je n'arrive pas à comprendre exactement comment gérer les threads lorsque j'utilise GeckoFX: il semble émettre constamment des erreurs lorsque j'essaie d'utiliser GeckoWebBrowser dans d'autres threads. En particulier, ce que j'essaie de faire dans cette application de test est de générer une vignette d'une page Web et de l'afficher sur un formulaire (pas le contrôle WebBrowser lui-même). Lorsque vous travaillez singlethreaded, il fonctionne très bien:Utilisation de GeckoFX dans une application multithread

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(); 
} 

Cependant, si je déplace la création de votre navigateur et le rendu dans son propre fil, je reçois une erreur de COM lorsque je tente d'appeler CreateControl():

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

Pour résoudre ce problème, je peux passer l'appel Xpcom.Initialize dans le fil ainsi:

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

cela fonctionne très bien ... une fois. La deuxième fois que j'essaie de naviguer, DocumentCompleted ne sera déclenché qu'une fois (avec environ: vide). Après un certain temps, une erreur COM apparaîtra également. Cela semble indiquer que l'appel de Xpcom.Initialize (une méthode statique qui ne peut être appelée qu'une seule fois par application, et qui ne fait rien à chaque fois) lie définitivement GeckoFX à ce thread spécifique. Pour toujours.

Existe-t-il un moyen de faire fonctionner correctement Xpcom et GeckoFX dans un environnement multithread?

+0

Avez-vous jamais quoi que ce soit sur la figure cette question? –

+0

Non ... le contexte était que j'utilisais GeckoFX dans les threads d'arrière-plan pour générer des miniatures de sites Web, et aussi en utilisant GeckoFX comme un navigateur réel dans l'interface utilisateur. J'ai fini par (malheureusement) utiliser le contrôle WebBrowser dans les threads d'arrière-plan pour générer des miniatures à la place (tout en utilisant GeckoFX dans l'interface utilisateur). – MisterZimbu

+0

C'est drôle ... c'est exactement ce que j'essaie de faire. J'ai eu un certain succès avec le contrôle WebBrowser via IE9, cependant. –

Répondre

0

Cela résoudra votre prob, le mettre à la fin de votre demande de navigation:

myGeckoFxBrowser.Navigate("about:blank"); 
myGeckoFxBrowser.Document.Cookie = ""; 
myGeckoFxBrowser.Stop(); 
0
GeckoFx can only be called from the same thread on which it was initialized (normally the UI thread) 

donc si vous voulez appeler GeckoFx contrôle, la méthode doit provenir du fil qui a initialisé le GeckoFx Contrôle, généralement son thread UI comme dans votre cas. vous pouvez utiliser BeginInvoke dans Form classe, essayez comme ceci:

 this.BeginInvoke(new Action(() => 
     { 
      browser.Navigate(txtUrl.Text); 
      //your code 
     })); 
Questions connexes