Pourquoi une erreur de RaceOnRCWCleanup lors de la fermeture d'un formulaire avec contrôle WebBrowser sur elle?

StackOverflow https://stackoverflow.com/questions/1874496

Question

VS2008, 2 .NET, VB.NET, XP ...

J'ai un formulaire Windows, avec un contrôle WebBrowser et un bouton Fermer, qui fait juste un Me.Close. Le bouton d'annulation du formulaire est définie sur le bouton Fermer, afin que je puisse frapper ESC pour fermer le formulaire.

Je mis la propriété DocumentText du contrôle WebBrowser en cas de charge, et l'affichage HTML.

L'exécution de l'application à partir de Visual Studio, si je clique sur le bouton Fermer, le formulaire se ferme sans erreur.

Si je clique sur le bouton ESC I get

  

RaceOnRCWCleanup a été détectée   Message: Une tentative a été faite pour   libérer un RCW qui est en cours d'utilisation. le RCW   est en cours d'utilisation sur le fil actif ou   un autre fil. Toute tentative de libérer un   en utilisation RCW peut causer la corruption ou   perte de données.

Si je lance l'application en dehors VS, je reçois pas d'erreur.

Toutes les idées a) pourquoi l'erreur, et b) la façon de prévenir ou de la supprimer?

Un grand merci à l'avance.

Était-ce utile?

La solution

Il est pas une erreur, il est un avertissement. Produit par un assistant Debugging géré (MDA), une extension du débogueur pour le code managé, qui pense qu'il voit quelque chose qui ne va pas dans votre code. La chaussure convient. Vous utilisez un RCW, WebBrowser est un contrôle COM. Vous tuer le RCW, vous fermez votre formulaire. Le MDA intervient parce qu'il pense qu'il est de voir le navigateur web utilisé et se faire tuer avant que la demande est terminée. Cela ferait normalement de sens que si vous utilisez un fil dans votre code.

Êtes-vous? Dans le cas contraire, ne perdez pas de dormir. COM utilise le comptage de référence, tristement célèbre pour ne pas être en mesure de résoudre les références circulaires.


D'accord, je suis un repro pour cela, rendue possible par les commentaires. Oui, cela est déclenché par la propriété ou la propriété CancelButton DialogResult du bouton du formulaire. Cela se produit lorsque la Banque mondiale a le focus, il voit la presse touche Escape. Une partie de la plomberie ActiveX est de dire le récipient à ce sujet afin qu'il puisse répondre à des frappes qui devraient avoir un effet secondaire. les raccourcis clavier, Tab, Entrée. Et Escape. Si le bouton se ferme alors la forme, le débogueur voit la Banque mondiale se sont disposés alors qu'il cadres de pile actifs à partir du code RCW sur la pile. Le danger est que cela pourrait provoquer un accident lors du retour de code appelé depuis le composant COM se sont libérés, il est pas rare.

En voyant cet accident est assez peu probable, mais je peux imaginer que cela pourrait exploser lorsque le thread finaliseur passe juste avant les retours d'événements Click du bouton. La solution de contournement pour le MDA et le crash potentiel est de retarder la fermeture de la forme jusqu'à ce que le code ActiveX cesse de fonctionner. Élégamment fait avec Control.BeginInvoke (). Comme ceci:

    private void CancelButton_Click(object sender, EventArgs e) {
        this.BeginInvoke((MethodInvoker)delegate { this.Close(); });
    }
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top