Pergunta

Eu tenho um controle WebBrowser que está sendo instanciado dinamicamente a partir de uma discussão de fundo STA porque o segmento pai é um BackgroundWorker e tem muitas outras coisas para fazer.

O problema é que o evento Navigated nunca dispara, a menos que eu estalar um MessageBox.Show () no método que contou a .Navigate (). Passo a 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;
}

Isso funciona bem; mas o messagebox vai ficar no caminho uma vez que este é um aplicativo de automação. Quando eu remover o MessageBox.Show (), o evento nunca incêndios WebBrowser.Navigated. Eu tentei suplantar esta linha com um Thread.Sleep (), e suspendendo o segmento pai.

Uma vez que eu tirar isso do caminho, tenho a intenção de suspender o segmento pai enquanto o WebBrowser está fazendo seu trabalho e encontrar alguma maneira de passar parte de trás HTML resultante para o segmento pai para que ele possa continuar com mais lógica.

Por que fazer isso? Como posso corrigi-lo?

Se alguém pode me fornecer uma maneira de buscar o conteúdo de uma página web, preencher alguns dados e retornar o conteúdo da página, do outro lado do botão enviar, tudo contra um servidor que não suporta verbos POST nem passar dados via QueryString, eu também vou aceitar essa resposta como todo este exercício terá sido desnecessária.


Solução: I terminou apenas não usar o fio BackgroundWorker e escravo em tudo com a sugestão do arquiteto equipa ... Embora em detrimento da capacidade de resposta: (

Foi útil?

Solução

WebBrowser não vai fazer muito menos que seja mostrado e tem um segmento interface do usuário associado; você está mostrando a forma na qual ele reside? Você precisa, para usar o DOM etc. O formulário pode ser fora da tela se você não quiser exibi-lo para o usuário, mas não vai funcionar bem em um serviço (por exemplo).

Para fins de raspagem, normalmente você pode simular um browwser HTML regular usando WebClient etc. isto não é suficiente? Você pode usar ferramentas como " Fiddler " para investigar o pedido exato que você precisa fazer para o servidor. Para mais do que isso, você pode olhar para o HTML agilidade Pack, que oferece acesso DOM para HTML sem um browser.

Outras dicas

Os eventos Navigated e DocumentComplete não incêndio, se a visibilidade do WebBrowser é definida como falsa. Você pode contornar essa limitação, fazendo o WebBrowser visível, mas defini-lo do local para que ele está fora da interface do usuário como:

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

você precisa adicionar uma linha que é assim:

webBrowser1.Navigated += new WebBrowserNavigatedEventHandler(webBrowser1_Navigated);

onde webBrowswer1_Navigated é a função que deseja chamado quando o evento é acionado.

Existe um fio GUI já começou? Talvez o objeto WebBrowser usa um thread de GUI para eventos punho. Nesse caso, você deve chamar Application.Run () do segmento que cria o WebBrowser (substituir seu MessageBox.Show () com isso). Application.Run () irá esperar até que Application.Exit () é chamado.

Tentando testar isso agora.

I terminou apenas não usar o fio BackgroundWorker e escravo em tudo com a sugestão do arquiteto equipa ... Embora em detrimento da capacidade de resposta :(

Um controle WebBrowser não pode funcionar se não estiver em um segmento STA. Se você quiser usar uma instância WebBrowser em um segmento que você precisa para criar sua linha e chamada Thread.SetApartmentState(ApartmentState.STA);

scroll top