2010-03-22 7 views
6

Est-il possible/recommandé d'utiliser des threads de travail d'arrière-plan avec le contrôle du navigateur Web?BackgroundWorker et WebBrowser Control

Je crée un bot qui recherche des mots-clés sur google, puis recherche les sites dans les 10 premières pages pour voir si un site est classé.

L'utilisateur peut fournir un maximum de 20 sites à vérifier et peut utiliser des proxies. Donc, idéalement, j'aimerais avoir 5 threads à la fois.

Est-ce possible? J'ai peut-être entendu dire qu'il y avait des problèmes avec le contrôle et les threads de WebBrowser.

Répondre

15

Ce n'est pas le cas. WebBrowser utilise Internet Explorer qui est un composant COM. Les composants COM ont un modèle de thread, IE utilise "Apartment". Ce qui est un mot coûteux qui signifie qu'il n'est pas sûr pour les threads. Vous êtes autorisé à appeler ses méthodes dans un BGW mais COM va automatiquement marshal l'appel au thread UI. Étant donné que tous les appels de méthode et les accès aux propriétés se produisent réellement sur le thread de l'interface utilisateur, vous le faites plus lent en utilisant un BGW.

Vous pouvez en fait exécuter WebBrowser sur un autre thread, vous devrez en créer une instance sur ce thread. Et vous devrez créer un fil qui est un soi-disant Single Threaded Apartment. STA, un acronyme que vous pourriez reconnaître à partir de l'attribut [STAThread] de la méthode Main() d'une application WinForms ou WPF. La modification d'un thread de travail en STA nécessite l'appel de Thread.SetApartmentState() avant de le démarrer. Vous ne pouvez pas faire cela pour un BGW. Et le thread doit pomper une boucle de message pour implémenter le contrat STA, il doit appeler Application.Run(). Requis, par exemple, pour que WebBrowser augmente ses événements. This answer montre l'approche.

Envisagez d'utiliser la classe WebRequest.

+3

+1 pour «Ce n'est pas»! –

+2

Je suis tombé sur cette réponse dans ma recherche pour savoir s'il est possible d'utiliser 'WebBrowser.Navigate()' ** not ** sur le thread de l'interface utilisateur. Ma compréhension de votre question que oui, c'est possible, mais ce ne serait pas grave parce que tous ces appels sont marshalés de toute façon sur le fil de l'interface utilisateur. Est-ce que je comprends bien? –

1

Y a-t-il une raison pour laquelle vous utilisez le contrôle IE sur une bibliothèque telle que HTML Agility pack? Cela a supporté le multithreading sans le cauchemar COM d'IE, et est beaucoup plus puissant avec l'analyse HTML.

+2

Le bot fait aussi des recherches par mot-clé et utilise d'autres outils de googles. Google est très strict sur les requêtes de bot, donc utiliser IE est beaucoup plus facile à gérer que d'utiliser HttpWebRequest. –

+3

Je me demande si ils ont une politique pour les robots en utilisant un navigateur. –

+0

@HenkHolterman Ils ont une politique contre tout ce qui pourrait nuire à leur service et leurs profits. –

1

Pour répondre à votre question immédiate: Je ne l'ai jamais essayé, mais cela ne me surprendrait pas s'il y avait des problèmes. Les contrôles WinForms en général ne sont pas destinés à être accessibles à partir de threads autres que le thread d'interface utilisateur principal. Vous devez utiliser la méthode Control.Invoke() pour exécuter des méthodes d'appel à partir d'autres threads. Cela les place dans le thread principal de l'interface utilisateur.

Pour résoudre le problème plus général: il vaut probablement mieux ne pas utiliser de contrôle WebBrowser si vous n'avez pas besoin de rendre le code HTML à l'utilisateur. Vous pouvez télécharger une page en utilisant la classe HttpWebRequest, ce qui est beaucoup plus léger. WebBrowser est essentiellement Internet Explorer intégré dans votre application.

Questions connexes