71 votes

Appartement mono-thread - impossible d'instancier un contrôle ActiveX

J'ai besoin d'obtenir des informations sur les styles CSS appliqués dans une page HTML. J'ai utilisé AxWebBrowser et j'itère sur IHTMLDOMNode. Je suis capable d'obtenir toutes les données dont j'ai besoin et de déplacer le code dans mon application. Le problème est que cette partie s'exécute à l'intérieur du travailleur en arrière-plan et j'ai une exception lorsque j'essaie d'instancier le contrôle.

AxWebBrowser browser = new AxWebBrowser();

Le contrôle ActiveX '8856f961-340a-11d0-a96b-00c04fd705a2' ne peut être instancié
car le thread actuel n'est pas dans un appartement monothread.

Y a-t-il un moyen de résoudre cela ou une autre option que AxWebBrowser?

93voto

JaredPar Points 333733

Le problème auquel vous êtes confronté est que la plupart des APIs de thread de fond / travailler créeront le thread dans un état d'appartement multithread. Le message d'erreur indique que le contrôle nécessite que le thread soit un appartement avec un seul thread.

Vous pouvez contourner cela en créant vous-même un thread et en spécifiant l'état d'appartement STA sur le thread.

var t = new Thread(MyThreadStartMethod);
t.SetApartmentState(ApartmentState.STA);
t.Start();

1 votes

Merci, super ça fonctionne. Encore une question/problème. La classe que j'utilise est juste "classe" et l'AxWebBrowser semble devoir être ajouté dans this.Controls(). Y a-t-il un moyen de simuler les Controls? Ou vais-je devoir avoir un formulaire séparé pour cela?

0 votes

@martin.malek Il n'y a pas de bonne façon de simuler cela. Le meilleur choix est de créer un nouveau formulaire.

1 votes

Salut, le code doit être t.SetApartmentState(ApartmentState.STA);

66voto

user764177 Points 271

Allez-y et ajoutez [STAThread] à l'entrée principale de votre application, cela indique que le modèle de threading COM est un appartement thread unique (STA)

exemple :

static class Program
{
    /// 
    /// Point d'entrée principal de l'application.
    /// 
    [STAThread]
    static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new WebBrowser());
    }
}

0 votes

Ne fonctionne pas dans le cadre 4.5 - donne des arguments invalides sur la dernière ligne

4voto

Ahmad Points 1454

Si vous avez utilisé [STAThread] comme point d'entrée principal de votre application et que vous obtenez toujours l'erreur, vous devrez peut-être effectuer un appel Thread-Safe au contrôle... quelque chose comme ci-dessous. Dans mon cas, avec le même problème, la solution suivante a fonctionné !

Private void YourFunc(..)
{
    if (this.InvokeRequired)
    {
        Invoke(new MethodInvoker(delegate()
        {
           // Appelez votre méthode YourFunc(..);
        }));
    }
    else
    {
        ///
    }

1voto

Grengas Points 616

Mon problème avec cela était que j'avais marqué ma méthode principale comme async. Je l'ai donc corrigé en la rendant simplement static void et en ajoutant .wait() à toutes les méthodes awaitables à l'intérieur.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X