多线程WebBrowser控件C#STA [英] MultiThreading WebBrowser Control C# STA

查看:214
本文介绍了多线程WebBrowser控件C#STA的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想打3个线程,每个运行WebBroswer控制。所以我想用线程池让一切变得简单

 的for(int i = 0;我3;;我++ )
{
ThreadPool.QueueUserWorkItem(新WaitCallback(gotoWork),I));
}
为WaitAll(waitHandles);



...... /



 无效gotoWork(对象o)
{
字符串URL =的String.Empty;
INT NUM =(INT)O;
开关(NUM)
{
的情况下0:
URL =google.com
中断;
案例1:
URL =yahoo.com;
中断;
案例2:
URL =bing.com;
中断;
}
web浏览器W =新WebBrower();
w.Navigate(URL);
}



不过,我得到一个错误说我需要一个STA线程该线程池会永远不会。 。之前尝试这个方法我试过这个

 发[] =螺纹螺纹[3]; 
的for(int i = 0;我3;;我++)
{
线由[i] =新主题(新ParameterizedStart(gotoWork);
线程[I] = SetApartmentState(ApartmentState.STA); //喔豪
线程[I] =启动();
}
的for(int i = 0;我3;;我++)
{
线程[I]。加入();
}

和在化网页浏览器全部初始化,一切看起来不错,但只多了一个两人竟会做任何事情,它从来没有一致的都没有。线程一直这样一场噩梦。任何人都可以提出一个很好的选择?


解决方案

 公共密封类SiteHelper:表
{
公共web浏览器mBrowser =新的web浏览器();
ManualResetEvent的mStart;
公共事件CompletedCallback完成;
公共SiteHelper(ManualResetEvent的开始)
{
mBrowser.DocumentCompleted + =新WebBrowserDocumentCompletedEventHandler(mBrowser_DocumentCompleted);
mStart =启动;完成(mBrowser)
}
无效mBrowser_DocumentCompleted(对象发件人,WebBrowserDocumentCompletedEventArgs E)
{
//生成完成事件
;
}
公共无效导航(字符串URL)
{
//开始导航
this.BeginInvoke(新动作(()=> mBrowser.Navigate(URL )));
}
公共无效终止()
{
//关闭的形式和消息循环
this.Invoke(新动作(()=> this.Close( )));
}
保护覆盖无效SetVisibleCore(布尔值)
{
如果(!IsHandleCreated)
{
//首次初始化,创建手柄和等待消息泵运行
this.CreateHandle();
this.BeginInvoke(新动作(()=> mStart.Set()));
}
//保留形式隐藏
值= FALSE;
base.SetVisibleCore(值);
}
}

这是其他类

 公共抽象类SiteManager:IDisposable的
{
私人的ManualResetEvent mStart;
私人SiteHelper mSyncProvider;
公共事件CompletedCallback完成;

公共SiteManager()
{
//启动线程,等待它初始化
mStart =新的ManualResetEvent(假);
线程t =新主题(startPump);
t.SetApartmentState(ApartmentState.STA);
t.IsBackground = TRUE;
t.Start();
mStart.WaitOne();
}
公共无效的Dispose()
{
//关闭消息循环和线程
mSyncProvider.Terminate();
}
公共无效导航(字符串URL)
{
//开始导航到一个URL
mSyncProvider.Navigate(URL);
}
公共无效mSyncProvider_Completed(web浏览器WB)
{
//导航完成,募集事件
CompletedCallback处理器=完成;
如果(处理!= NULL)
{
处理器(WB);
}
}
私人无效startPump()
{
//开始消息循环
mSyncProvider =新SiteHelper(mStart);
mSyncProvider.Completed + = mSyncProvider_Completed;
Application.Run(mSyncProvider);
}
}


类测试仪:SiteManager
{
公共测试仪()
{
SiteEventArgs AR =新SiteEventArgs(MeSite);

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

无效Tester_Completed(web浏览器WB)
{
MessageBox.Show(测试);
如果(wb.DocumentTitle ==你好)

base.mSyncProvider_Completed(WB);
}

//保护覆盖无效mSyncProvider_Completed(web浏览器WB)
// {
// // MessageBox.Show(过载测试);
// //base.mSyncProvider_Completed(wb,AR);
//}
}

在您的主要形式有:



 私人无效的button1_Click(对象发件人,EventArgs五)
{
//测试泵=新测试仪();
//pump.Completed + =新CompletedCallback(pump_Completed);
//pump.Navigate(\"www.cnn.com);

测试泵2 =新测试仪();
pump2.Completed + =新CompletedCallback(pump_Completed);
pump2.Navigate(www.google.com);
}


I want to make 3 threads that each run the WebBroswer control. So I would like to use the ThreadPool to make things easy.

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

But I get an error saying that I need a STA thread which the ThreadPool will never be. Before trying this method I tried this.

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

And the WebBrowsers all initialized and everything looks good but only one more two will actually do anything and its never consistant at all. Threading has been such a nightmare. Can anybody suggest a nice alternative?

解决方案

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

An other class as

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

On your main form:

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控件C#STA的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆