MultiThreading WebBrowser控件C#STA

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

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

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

您需要在某个地方托管webbrowser控件才能使其工作(将其添加到表单中),其次您应该使用主机控件(或类似委托)的Invoke()(如Form.Invoke())与WebBrowser控件进行交互。

现在不需要提醒但是,你的线程应该是STA

您可以使用此类类来托管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(); } } } 

毕竟我选择了这个解决方案: http : //watin.sourceforge.net/documentation.html

在你的情况下你应该这样做:

 ... Thread thread = new Thread(SomeMethod); thread.SetApartmentState(ApartmentState.STA); ...