2010-12-23 16 views
1

WebBrowserを作成し、それぞれに特定の処理を行うマルチスレッドアプリケーションを作成しようとしています。私がコードをスレッドから実行するように変更したとき、コードは正常に実行され、InvokeMember("click")が呼び出され、何も起こらなくなります。 InvokeMember()は実行されず、ボタンのクリックは行われません。スレッド内のWebBrowserコントロールでInvokeMember( "click")が動作しない

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", "[email protected]"); 
    wb.Document.GetElementById("F4").SetAttribute("Value", "[email protected]"); 
    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; 
     } 
    } 
} 

それがメインスレッドから呼ばれていたときに仕事は()非常に正常に実行されることに注意してください:ここに私のコードです。問題は別のスレッドから呼び出すことにあります。

ありがとうございます。

答えて

1

あなたがSTAスレッドのハード要件に違反している、それはメッセージループをポンプしなければなりません。 Application.DoEvents()を呼び出すことで、Navigateメソッドの問題を回避できます。それはメッセージループをポンピングします。しかし、InvokeClickではこれをやっていません。

解決策はthis answerにチェックしてください。コードをDocumentCompletedイベントに配置します。スレッドをいつ停止するかを決めるには明らかな方法はありません。タイマーでクリックの副作用を調査する必要があります。

+0

多くのおかげでハンス、それは魅力のように働いています。 – deadlock

0

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"); 
+0

これで問題は解決しません。返信いただきありがとうございます。 – deadlock

関連する問題