簡體   English   中英

InvokeMember(“ click”)在線程內的webBrowser控件中不起作用

[英]InvokeMember(“click”) doesn't work in webBrowser control inside a thread

我正在嘗試創建一個多線程應用程序,該應用程序創建WebBrowsers並對每個應用程序執行特定操作。 當我從主線程嘗試代碼時,它工作得很好,但是,當我將代碼更改為從線程運行時,代碼運行良好,直到InvokeMember("click")並且沒有任何反應。 InvokeMember()未執行,並且按鈕單擊沒有發生。 這是我的代碼:

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;
        }
    }
}

請注意,從主線程調用Work()時,它運行非常正確。 問題在於從另一個線程調用它。

提前致謝。

您違反了對STA線程的嚴格要求,它必須泵送消息循環。 您可以通過調用Application.DoEvents()使用Navigate方法來修補問題。 這推動了消息循環。 但是您沒有為InvokeClick執行此操作。

檢查此答案以獲取解決方案。 將代碼放在DocumentCompleted事件中。 我沒有明顯的方法來決定何時停止線程,您可能不得不使用計時器來輪詢單擊的某種副作用。

JFYI,接下來可以使用LINQ:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM