2009-12-09 24 views
20

VS2008, .NET 2, VB.NET, XP ...¿Por qué un error RaceOnRCWCleanup al cerrar un formulario con control WebBrowser en él?

que tiene una forma de Windows, con un control WebBrowser y un botón Cerrar, que sólo hace un Me.Close. El botón de cancelación del formulario está configurado en el botón Cerrar, para que pueda presionar ESC para cerrar el formulario.

Establecí la propiedad DocumentText del control WebBrowser en el evento de carga y se muestra el HTML.

Ejecutando la aplicación de Visual Studio, si hago clic en el botón Cerrar, el formulario se cierra sin ningún error.

Si pulso el botón ESC me sale

RaceOnRCWCleanup se detectó Mensaje: Se ha hecho un intento de libre de un RCW que está en uso. El RCW está en uso en el hilo activo o otro hilo. Intentar liberar un en uso RCW puede causar daños o la pérdida de datos .

Si ejecuto la aplicación fuera de VS, no obtengo ningún error.

Alguna idea a) por qué el error, yb) cómo prevenirlo o suprimirlo?

Muchas gracias de antemano.

Respuesta

30

No es un error, es una advertencia. Producido por un Asistente de depuración gestionada (MDA), una extensión del depurador para código administrado, que cree que está viendo que algo va mal en su código. El zapato se ajusta Está utilizando un RCW, WebBrowser es un control COM. Estás matando al RCW, estás cerrando tu formulario. El MDA interviene porque cree que está viendo el navegador web en uso y lo está matando antes de que se complete la solicitud. Eso normalmente solo tendría sentido si estás usando un hilo en tu código.

¿Usted? Si no, no pierdas el sueño por ello. COM usa recuento de referencias, notorio por no poder resolver referencias circulares.


Bien, obtuve un repro para esto, habilitado por los comentarios. Sí, esto se desencadena mediante la propiedad CancelButton del formulario o la propiedad DialogResult del botón. Esto sucede cuando el WB tiene el foco, ve la tecla Escape presionada. Parte de la instalación de plomería de ActiveX es informar al contenedor al respecto para que pueda responder a las pulsaciones de teclas que deberían tener un efecto secundario. Atajos de teclado, Tab, Enter. Y Escape. Si el botón cierra el formulario, el depurador verá que el WB se eliminará mientras haya cuadros de pila activos del código RCW en la pila. El peligro es que esto podría causar un bloqueo cuando el código invocado regrese desde que se lanzó el componente COM, no es raro.

Ver esta caída es bastante improbable, pero me puedo imaginar que esto podría causar una explosión cuando la secuencia del finalizador se ejecute justo antes de que el evento Click del botón regrese. La solución para MDA y la falla potencial es retrasar el cierre del formulario hasta después de que el código ActiveX deje de ejecutarse. Elegantemente hecho con Control.BeginInvoke(). De esta manera:

private void CancelButton_Click(object sender, EventArgs e) { 
     this.BeginInvoke((MethodInvoker)delegate { this.Close(); }); 
    } 
+2

No, todo está sucediendo en el hilo de primer plano. No es el hecho de que esté sucediendo en absoluto lo que me molesta, hay formas de apagarlos en VS.Es el hecho de que si se invoca el controlador de eventos Close haciendo clic en el botón Cerrar, * no * sucede, pero si se invoca el mismo controlador presionando ESC (ya que el botón Cerrar es la propiedad del botón Cancelar del formulario), * hace*. ¿Por qué la diferencia? – ChrisA

+2

Veo este escenario exacto ... no es un problema para mí, porque QUIERO cerrar el formulario con el webBrowser en él. Me gustaría entender por qué hay una diferencia entre presionar ESC y hacer clic en la 'X'. – mpeterson

+0

@chris, @mpeterson - obtuve una reproducción y una solución, publicación actualizada. –

Cuestiones relacionadas