Perché un errore di RaceOnRCWCleanup quando si chiude un modulo con controllo WebBrowser su di esso?
-
18-09-2019 - |
Domanda
VS2008, NET 2, VB.NET, XP ...
Ho una forma di Windows, con un controllo WebBrowser e un pulsante Chiudi, che ha appena fa un Me.Close
. pulsante di annullamento del modulo è impostato sul pulsante Chiudi, in modo che possa colpire ESC per chiudere il modulo.
Ho impostato la proprietà DocumentText
del controllo WebBrowser in caso di carico, ei display HTML.
L'esecuzione l'applicazione da Visual Studio, se si fa clic sul pulsante Chiudi, la forma si chiude senza errori.
Se premo il tasto ESC ottengo
RaceOnRCWCleanup è stato rilevato Messaggio: Un tentativo è stato fatto per liberare un RCW che è in uso. l'RCW è in uso sul filetto attiva o altro thread. Il tentativo di liberare un in uso RCW può causare il danneggiamento o la perdita di dati.
Se eseguo l'applicazione al di fuori VS, ottengo nessun errore.
Tutte le idee a) Perché l'errore, e b) come prevenire o sopprimerla?
Molte grazie in anticipo.
Soluzione
Non è un errore, è un avvertimento. Prodotto da un debug Assistente Managed (MDA), un'estensione del debugger per il codice gestito, che pensa che sta vedendo qualcosa che non va nel codice. La scarpa si adatta. Si sta utilizzando un RCW, WebBrowser è un controllo COM. Si sta uccidendo il RCW, si sta chiudendo il modulo. La MDA interviene perché pensa che sta vedendo il browser web in uso ed essere uccisi prima che la richiesta è stata completata. Che normalmente hanno senso solo se si utilizza un thread nel codice.
Sei? In caso contrario, non perdere il sonno su di esso. COM utilizza il conteggio di riferimento, noti per non essere in grado di risolvere i riferimenti circolari.
Va bene, ho ottenuto un Repro per questo, ha consentito dai commenti. Sì, questo è innescato da proprietà CancelButton della forma o proprietà DialogResult del pulsante. Questo accade quando il WB ha il focus, si vede la pressione del tasto ESC. Parte del l'impianto idraulico ActiveX è quello di raccontare il contenitore su di esso in modo che possa rispondere alle sequenze di tasti che dovrebbe avere un effetto collaterale. battiture della scorciatoia, Tab, Invio. E fuggire. Se il pulsante chiude allora la forma, il debugger vede WB sempre disposta mentre ci sono stack frame attivi dal codice RCW in pila. Il pericolo è che questo potrebbe causare un crash quando l'utente chiamato restituisce il codice in quanto il componente COM è stato rilasciato, non è raro.
Vedendo questo incidente è piuttosto improbabile, ma posso immaginare che questo potrebbe bombardare quando il filo finalizzatore corre poco prima del ritorno di evento Click del pulsante. La soluzione per la MDA e l'incidente potenziale è quello di ritardare la chiusura del modulo fino a dopo il codice ActiveX smette di funzionare. Elegantemente fatto con Control.BeginInvoke (). In questo modo:
private void CancelButton_Click(object sender, EventArgs e) {
this.BeginInvoke((MethodInvoker)delegate { this.Close(); });
}