Esperando WebBrowser contenido ajax

Quiero pausar la ejecución de mi hilo hasta una determinada div se ha cargado mediante ajax en un WebBrowser instancia. Obviamente, yo continuamente se puede comprobar la presencia de este div hacer algo como:

while (Browser.Document.GetElementById("divid") == null) { Thread.Sleep(200); }

Sin embargo, dormir en el hilo que el Navegador está en entre los bucles que se bloquea el navegador de realidad cargar el contenido en el primer lugar. Parece, por tanto, que necesito para ejecutar el Browser.Navigate método en un hilo separado – entonces puedo continuar comprobar y espere a que la presencia de la div mientras que el WebBrowser instancia continúa la carga de la URL me la pedía.

De mis intentos en este, sin embargo, han fallado y me gustaría valor de cualquier entrada sobre cómo debería ir sobre esto. Pensé que simplemente el envío de un nuevo hilo con new Thread(() => { Browser.Navigate(url); }); que trabajar, pero después de hacerlo, nada cargas y el Navegador.ReadyState permanece como ‘sin inicializar’. Supongo que estoy un malentendido de cómo ir sobre adecuadamente roscado procedimientos como este con C# y pondría en valor algunos consejos!

InformationsquelleAutor JoeR | 2010-09-25

4 Kommentare

  1. 6

    No bloquear el hilo principal mensaje de la bomba. Ya que el navegador es un componente STA, xmlhttprequest no será capaz de crear eventos desde el subproceso en segundo plano si se bloquea el mensaje de la bomba.
    Usted no puede navegar en un subproceso en segundo plano. El contenedor de Formularios Windows de la ActiveX webbrowser no admite el acceso de otros hilos que el subproceso de interfaz de usuario. El uso de un temporizador en su lugar.

    • Puede usted por favor, pon el temporizador de enfoque? Podemos añadir un retardo de 1 segundo antes de disparar el DocumentCompleted Evento?
    • No, pero puedes motor de arranque de un temporizador, a continuación, analizar el documento en su evento tick, suponiendo que la operación de ajax termina antes de que el temporizador de garrapatas. Recuerde que para detener el temporizador cuando se realiza el análisis.
  2. 7

    El siguiente trabajo,

    while (Browser.Document.GetElementById("divid") == null) 
    { 
        Application.DoEvents();
        Thread.Sleep(200); 
    }

    La anteriormente trabajó para mí…

    • Hice el experimento con algo similar pero en el extremo utilizado Sheng Jiang método. Parecía ser la más «correcta» forma de hacerlo.
    • ¿qué pasa si el div no está completamente cargado?
  3. 0

    Usted puede encontrar un texto en el cuerpo por ejemplo:

    while (HtmlWindow.Document.Body.InnerHtml.Contains(some_text) == false)
    {        
        Application.DoEvents();
        Thread.Sleep(200);
    }
  4. 0

    No debe llamar a Thread.Sleep como se bloquea el subproceso de interfaz de usuario.

    La mejor solución es crear una tarea asincrónica. Dentro de esta tarea puede llamar Task.Delay que no interfiera con la interfaz de usuario.

    static async Task<IHTMLElement> WaitForElement(WebBrowser browser, string elementID, TimeSpan timeout)
    {
        long startTime = DateTimeOffset.Now.ToUnixTimeMilliseconds();
        var timeoutMS = timeout.TotalMilliseconds;
    
        //While the timeout has not passed...
        while (DateTimeOffset.Now.ToUnixTimeMilliseconds() - startTime < timeoutMS)
        {
            //Wait for 200ms
            await Task.Delay(TimeSpan.FromMilliseconds(200));
    
            //Check if the document contains the element
            var document = (HTMLDocument) browser.Document;
            var element = document.getElementById(elementID);
            if (element != null)
            {
                //Element found, stop looping
                return element;
            }
        }
    
        throw new Exception($"Element was not loaded after {timeoutMS} milliseconds");
    }

    El código anterior comprueba el DOM cada 200 milisegundos para ver si el elemento con el ID existe. También contiene un tiempo de espera (por ejemplo, 10 segundos) en caso de que el elemento nunca se carga por alguna razón inesperada.

    Aquí es un ejemplo que muestra cómo utilizar esta función para leer el valor de un campo de texto añadido en el documento después de una llamada AJAX:

    var input = (IHTMLInputElement) await WaitForElement(myBrowserControl, "input-id", TimeSpan.FromSeconds(10));
    var value = input.value; //Read the value of the input field

Kommentieren Sie den Artikel

Bitte geben Sie Ihren Kommentar ein!
Bitte geben Sie hier Ihren Namen ein

Pruebas en línea