Pregunta

Tengo un control WebBrowser que está siendo instanciado dinámicamente desde un subproceso de fondo STA porque el hilo de los padres es un BackgroundWorker y tiene un montón de otras cosas que hacer.

El problema es que el evento Navigated no se dispara nunca, a menos que me pop una MessageBox.Show () en el método que dijo que .Navigate (). Me explicaré:

ThreadStart ts = new ThreadStart(GetLandingPageContent_ChildThread);
Thread t = new Thread(ts);
t.SetApartmentState(ApartmentState.STA);
t.Name = "Mailbox Processor";
t.Start();

protected void GetLandingPageContent_ChildThread()
{
 WebBrowser wb = new WebBrowser();
 wb.Navigated += new WebBrowserNavigatedEventHandler(wb_Navigated);
 wb.Navigate(_url);
 MessageBox.Show("W00t");
}

protected void wb_Navigated(object sender, WebBrowserNavigatedEventArgs e)
{
 WebBrowser wb = (WebBrowser)sender; // Breakpoint
 HtmlDocument hDoc = wb.Document;
}

Esto funciona bien; pero el cuadro de mensaje se interpone en el camino ya que esta es una aplicación de automatización. Cuando quito el MessageBox.Show (), el evento WebBrowser.Navigated nunca se disparará. He intentado suplantar esta línea con un Thread.Sleep (), y mediante la suspensión de la rosca de los padres.

Una vez que tengo esta fuera del camino, me propongo suspender el hilo de los padres, mientras que el WebBrowser está haciendo su trabajo y encontrar alguna manera de pasar el código HTML resultante de nuevo a la rosca de los padres para que pueda seguir con más lógica.

¿Por qué hace esto? ¿Cómo puedo solucionarlo?

Si alguien me puede proporcionar una manera de buscar el contenido de una página web, rellenar unos datos y devolver el contenido de la página en el otro lado del botón de enviar, todos contra un servidor web que no es compatible verbos de la POST ni de pasar datos a través de una cadena de consulta, yo también voy a aceptar esa respuesta como todo este ejercicio habrán sido innecesario.


Solución: Acabé no usar el hilo BackgroundWorker y esclavo en absoluto a sugerencia del arquitecto equipo ... Aunque a expensas de la capacidad de respuesta: (

¿Fue útil?

Solución

WebBrowser no hará mucho menos que se muestra y tiene un hilo de interfaz de usuario asociado; se le muestra la forma en la que reside? Es necesario, utilizar el DOM etc. La forma podría ser fuera de la pantalla si no desea que se muestre al usuario, pero no va a funcionar bien en un servicio (por ejemplo).

Para los propósitos de raspado, normalmente se puede simular un browwser HTML regular usando WebClient etc. esto no es suficiente? Puede utilizar herramientas como " violinista " para investigar la solicitud exacta que necesita para hacer que el servidor. Por más que eso, lo podría hacer en el href="http://www.codeplex.com/htmlagilitypack" rel="nofollow noreferrer">

Otros consejos

Los eventos navegado y DocumentComplete no se disparará si la visibilidad del WebBrowser se establece en false. Puede evitar esta limitación, haciendo que el WebBrowser visible pero establecer su ubicación por lo que está fuera de la interfaz de usuario como:

wb.Visible = true;
wb.Left = -wb.Width; // notice the minus sign

es necesario agregar una línea que es como sigue:

webBrowser1.Navigated += new WebBrowserNavigatedEventHandler(webBrowser1_Navigated);

donde webBrowswer1_Navigated es la función que desee llama cuando se activa el evento.

¿Hay un hilo de interfaz gráfica de usuario ya ha comenzado? Tal vez el objeto WebBrowser utiliza un hilo de interfaz gráfica de usuario para controlar los eventos. En ese caso, debe llamar Application.Run () del hilo que crea el WebBrowser (reemplazar su MessageBox.Show () con esto). Application.Run () se bloquea hasta que Application.Exit () se llama.

Tratando de probar esto ahora.

Acabé no usar el hilo BackgroundWorker y esclavo en absoluto a sugerencia del arquitecto equipo ... Aunque a expensas de la capacidad de respuesta :(

Un control WebBrowser no puede funcionar si no está en un subproceso STA. Si desea utilizar una instancia de WebBrowser en un hilo que necesita para crear su hilo y llamada Thread.SetApartmentState(ApartmentState.STA);

scroll top