MultiThreading WebBrowser控件C#STA

Pro*_*imo 5 c# multithreading webbrowser-control

我想制作3个线程,每个线程运行WebBroswer控件.所以我想使用ThreadPool让事情变得简单.

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

....../

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);
}
Run Code Online (Sandbox Code Playgroud)

但是我得到一个错误,说我需要一个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();
}
Run Code Online (Sandbox Code Playgroud)

WebBrowsers全部初始化,一切看起来都不错,但只有两个实际上会做任何事情而且它永远不会一致.线程一直是个噩梦.任何人都能提出一个不错的选择吗?

小智 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);
    }
}
Run Code Online (Sandbox Code Playgroud)

另一个类如

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);
    //}
}
Run Code Online (Sandbox Code Playgroud)

在您的主表单上:

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");
}
Run Code Online (Sandbox Code Playgroud)