2009-08-09 26 views
3

それぞれがWebBroswerコントロールを実行する3つのスレッドを作成します。ですから、私はThreadPoolを使いやすくしたいと思います。MultiThreading WebBrowserコントロールC#STA

for(int i = 0;i < 3;i++) 
{ 
    ThreadPool.QueueUserWorkItem(new WaitCallback(gotoWork), i)); 
} 
WaitAll(waitHandles); 

....../

void gotoWork(object o) 
{ 
    string url = String.Empty; 
    int num = (int)o; 
    switch(num) 
    { 
    case 0: 
     url = "google.com"; 
     break; 
    case 1: 
     url = "yahoo.com"; 
     break; 
    case 2: 
     url = "bing.com"; 
     break; 
    } 
    WebBrowser w = new WebBrower(); 
    w.Navigate(url); 
} 

しかし、私はThreadPoolのはなることはありませんSTAスレッドを必要とするというエラーを取得します。この方法を試す前に私はこれを試しました。

Thread[] threads = Thread[3]; 
for(int i = 0;i < 3;i++) 
{ 
    threads[i] = new Thread(new ParameterizedStart(gotoWork); 
    threads[i] = SetApartmentState(ApartmentState.STA); //whoo hoo 
    threads[i] = Start(); 
} 
for(int i = 0; i < 3;i++) 
{ 
    threads[i].Join(); 
} 

そしてWebBrowsersすべて初期化され、すべてがよさそうだが、一つだけより2は、実際に何かをし、そのすべてで一貫することはありません。スレッディングはそのような悪夢です。誰も良い代替案を提案することはできますか?

+0

一度に複数のページをロードするのはなぜ? WebBrowserが必要なのか、HttpWebRequestの仕事が必要ですか(たとえば、ページを表示する必要がありますか、ページ上でJavaScriptを実行する必要がありますか)。 Webクローリング/スクレイピングを行う場合は、より効率的な方法があります。 – Chad

答えて

0
public sealed class SiteHelper : Form 
{ 
    public WebBrowser mBrowser = new WebBrowser(); 
    ManualResetEvent mStart; 
    public event CompletedCallback Completed; 
    public SiteHelper(ManualResetEvent start) 
    { 
     mBrowser.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(mBrowser_DocumentCompleted); 
     mStart = start; 
    } 
    void mBrowser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e) 
    { 
     // Generated completed event 
     Completed(mBrowser); 
    } 
    public void Navigate(string url) 
    { 
     // Start navigating 
     this.BeginInvoke(new Action(() => mBrowser.Navigate(url))); 
    } 
    public void Terminate() 
    { 
     // Shutdown form and message loop 
     this.Invoke(new Action(() => this.Close())); 
    } 
    protected override void SetVisibleCore(bool value) 
    { 
     if (!IsHandleCreated) 
     { 
      // First-time init, create handle and wait for message pump to run 
      this.CreateHandle(); 
      this.BeginInvoke(new Action(() => mStart.Set())); 
     } 
     // Keep form hidden 
     value = false; 
     base.SetVisibleCore(value); 
    } 
} 

メインフォーム上

public abstract class SiteManager : IDisposable 
{ 
    private ManualResetEvent mStart; 
    private SiteHelper mSyncProvider; 
    public event CompletedCallback Completed; 

    public SiteManager() 
    { 
     // Start the thread, wait for it to initialize 
     mStart = new ManualResetEvent(false); 
     Thread t = new Thread(startPump); 
     t.SetApartmentState(ApartmentState.STA); 
     t.IsBackground = true; 
     t.Start(); 
     mStart.WaitOne(); 
    } 
    public void Dispose() 
    { 
     // Shutdown message loop and thread 
     mSyncProvider.Terminate(); 
    } 
    public void Navigate(string url) 
    { 
     // Start navigating to a URL 
     mSyncProvider.Navigate(url); 
    } 
    public void mSyncProvider_Completed(WebBrowser wb) 
    { 
     // Navigation completed, raise event 
      CompletedCallback handler = Completed; 
      if (handler != null) 
      { 
       handler(wb); 
      } 
    } 
    private void startPump() 
    { 
     // Start the message loop 
     mSyncProvider = new SiteHelper(mStart); 
     mSyncProvider.Completed += mSyncProvider_Completed; 
     Application.Run(mSyncProvider); 
    } 
} 


class Tester :SiteManager 
{ 
    public Tester() 
    { 
     SiteEventArgs ar = new SiteEventArgs("MeSite"); 

     base.Completed += new CompletedCallback(Tester_Completed); 
    } 

    void Tester_Completed(WebBrowser wb) 
    { 
     MessageBox.Show("Tester"); 
     if(wb.DocumentTitle == "Hi") 

     base.mSyncProvider_Completed(wb); 
    } 

    //protected override void mSyncProvider_Completed(WebBrowser wb) 
    //{ 
    // // MessageBox.Show("overload Tester"); 
    // //base.mSyncProvider_Completed(wb, ar); 
    //} 
} 

などの他のクラス:

private void button1_Click(object sender, EventArgs e) 
{ 
    //Tester pump = new Tester(); 
    //pump.Completed += new CompletedCallback(pump_Completed); 
    //pump.Navigate("www.cnn.com"); 

    Tester pump2 = new Tester(); 
    pump2.Completed += new CompletedCallback(pump_Completed); 
    pump2.Navigate("www.google.com"); 
} 
+0

これはそれぞれスローされますスレッドにナビゲートして実行を続行しますか?もしそうなら、各スレッドごとに新しいTesterオブジェクトが必要ですか? – xendi

0

フォームを動作させるためにWebブラウザコントロールをホストする必要があります。次に、Form.Invoke()などのホストコントロール(または同様のデリゲート)のInvoke()を使用して、 WebBrowserコントロールを使用します。

今思い出さする必要はありませんが、そう、あなたのスレッドがSTA

0

する必要がありますあなたは、WebBrowserコントロールをホストするためにあなたの目的のために、クラスのようなタイプを使用することができます:私はこれを選択し、すべての後

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Windows.Forms; 

namespace SomeNameSpace 
{ 
    public class WebForm : Form 
    { 
     public WebBrowser WebBrowser { get; set; } 

     public WebForm() 
     { 
      WebBrowser = new WebBrowser(); 
     } 
    } 
}