InvokeMember (“click”) não funciona no controle webBrowser dentro de um thread

Eu estou tentando criar um aplicativo multi-threaded que cria WebBrowsers e faz coisas específicas para cada um. Quando eu tentei meu código do thread principal funcionou muito bem, no entanto, quando eu mudei o código para executar a partir de um segmento, o código é executado até InvokeMember("click") é chamado e nada acontece. InvokeMember() não é executado e o clique do botão não ocorre. Aqui está o meu código:

 private void button1_Click(object sender, EventArgs e) { Thread t = new Thread(Work); t.SetApartmentState(ApartmentState.STA); t.Start(); } [STAThread] void Work() { WebBrowser wb = new WebBrowser(); wb.ScriptErrorsSuppressed = false; wb.Visible = true; wb.Navigate("http://website.com"); while (wb.ReadyState != WebBrowserReadyState.Complete) { Application.DoEvents(); } //updateText("Loaded"); wb.Document.GetElementById("F1").SetAttribute("Value", "Test"); wb.Document.GetElementById("F2").SetAttribute("Value", "Saracostaz"); wb.Document.GetElementById("F3").SetAttribute("Value", "Tester5123@hotmail.com"); wb.Document.GetElementById("F4").SetAttribute("Value", "Tester5123@hotmail.com"); wb.Document.GetElementById("F5").SetAttribute("Value", "limewire"); wb.Document.GetElementById("F6").SetAttribute("SelectedIndex", "1"); wb.Document.GetElementById("F7").SetAttribute("SelectedIndex", "2"); wb.Document.GetElementById("F8").SetAttribute("SelectedIndex", "5"); wb.Document.GetElementById("F9").SetAttribute("SelectedIndex", "20"); // updateText("Entered Data"); HtmlElementCollection elements = wb.Document.Body.All; foreach (HtmlElement element in elements) { string valueAttribute = element.GetAttribute("value"); if (!string.IsNullOrEmpty(valueAttribute) && valueAttribute == "Sign Up") { element.InvokeMember("click"); //MessageBox.show("I am in"); //that messagebox shows normally. break; } } } 

Por favor, note que o trabalho () é executado corretamente quando é chamado do thread principal. O problema está em chamá-lo de outro segmento.

Desde já, obrigado.

Você está violando um requisito difícil para um segmento STA, ele deve bombear um loop de mensagem. Você corrigiu sua maneira de resolver o problema com o método Navigate chamando Application.DoEvents (). Isso bombeia o loop de mensagens. Mas você não está fazendo isso para InvokeClick.

Verifique esta resposta para a solução. Coloque o código no evento DocumentCompleted. Não há uma maneira óbvia de decidir quando parar o tópico, você teria que pesquisar algum tipo de efeito colateral do clique com um timer, talvez.

JFYI, você pode fazer o próximo usando LINQ:

 var element = elements .OfType() .Select(element => element.GetAttribute("value")) .FirstOrDefault(value=> String.Equals(value, "Sign Up")); if (element != null) element.InvokeMember("click");