WebBrowser 多线程问题,寻求解答!(已经搞清楚!) 【转】

 1 using System;
 2 using System.Threading;
 3 using System.Windows.Forms;
 4 
 5 namespace WebBrowserTest
 6 {
 7     public partial class MainForm : Form
 8     {
 9         public MainForm()
10         {
11             InitializeComponent();
12         }
13 
14         public static ChildForm childForm;
15 
16         private void MainForm_Load(object sender, EventArgs e)
17         {
18             this.Text = string.Format("线程ID:{0}", Thread.CurrentThread.ManagedThreadId);
19         }
20 
21         private void button1_Click(object sender, EventArgs e)
22         {
23             Thread thread = new Thread(new ThreadStart(this.CreateForm));
24             thread.SetApartmentState(ApartmentState.STA);
25             thread.IsBackground = true;
26             thread.Start();
27         }
28 
29         private void CreateForm()
30         {
31             MainForm.childForm = new ChildForm();
32             MainForm.childForm.webBrowser.Navigate("http://tieba.baidu.com/"); //这里不是UI线程,为什么也能导航呢?
33             MainForm.childForm.ShowDialog();
34         }
35 
36         private void button2_Click(object sender, EventArgs e)
37         {
38             if (MainForm.childForm != null && MainForm.childForm.IsHandleCreated)
39             {
40                 //如果不调用childForm窗口的Invoke方法修改标题,就报异常!
41                 //线程间操作无效: 从不是创建控件“ChildForm”的线程访问它。
42 
43                 MainForm.childForm.Invoke(new MethodInvoker(delegate
44                 {
45                     MainForm.childForm.Text = string.Format("线程ID:{0}", Thread.CurrentThread.ManagedThreadId);
46                 }));
47 
48 
49 
50                 //为什么这里就能正常导航页面呢?
51                 //难道WebBrowser控件,始终都在UI线程运行?
52                 //即使创建它的线程,不是UI线程?
53 
54                 MainForm.childForm.webBrowser.Navigate("http://www.baidu.com/");
55             }
56         }
57     }
58 }

 

 

 

 

 

但是神奇的地方就是,操作WebBrowser进行网页导航,就可以不调用 Invoke 方法,不报异常。这是为什么呢?

这个环境下 WebBrowser 是运行在那个线程呢? 主线程? 还是新的子线程?

 

简化代码后,结果一样。

 

复制代码
using System;
using System.Threading;
using System.Windows.Forms;

namespace WebBrowserTest
{
    public partial class MainForm : Form
    {
        public MainForm()
        {
            InitializeComponent();
        }

        private Form childForm;
        private WebBrowser webBrowser;

        private void MainForm_Load(object sender, EventArgs e)
        {
            this.Text = string.Format("线程ID:{0}", Thread.CurrentThread.ManagedThreadId);
        }

        private void button1_Click(object sender, EventArgs e)
        {
            Thread thread = new Thread(new ThreadStart(this.CreateForm));
            thread.SetApartmentState(ApartmentState.STA);
            thread.IsBackground = true;
            thread.Start();
        }

        private void CreateForm()
        {
            this.childForm = new Form();

            this.webBrowser = new WebBrowser();
            this.webBrowser.Dock = DockStyle.Fill;

            this.childForm.Controls.Add(this.webBrowser);

            this.webBrowser.Navigate("http://tieba.baidu.com/"); //这里不是UI线程,为什么也能导航呢?

            this.childForm.ShowDialog();
        }

        private void button2_Click(object sender, EventArgs e)
        {
            if (this.childForm != null && this.childForm.IsHandleCreated)
            {
                //如果不调用childForm窗口的Invoke方法修改标题,就报异常!
                //线程间操作无效: 从不是创建控件“ChildForm”的线程访问它。

                this.childForm.Invoke(new MethodInvoker(delegate
                {
                    this.childForm.Text = string.Format("线程ID:{0}", Thread.CurrentThread.ManagedThreadId);
                    //这样修改是正常的。
                }));

                this.childForm.Text = "修改标题"; //这样修改就报异常了!

                //为什么这里就能正常导航页面呢?
                //难道WebBrowser控件,始终都在UI线程运行?
                //即使创建它的线程,不是UI线程?

                this.webBrowser.Navigate("http://www.baidu.com/");
            }
        }
    }
}
复制代码

 

 

此问题寻求解答,

目的:

现在多标签浏览器 它每个标签都是一个线程在执行

其中一个标签页面 崩溃 不影响到其他 标签页面

 

新线程创建带有WebBrowser控件的窗口,

实现多线程加速,

如果一个网页崩溃,不会导致整个程序关闭。

源码下载:http://files.cnblogs.com/kofip/WebBrowserTest.rar

简化后源码:http://files.cnblogs.com/kofip/WebBrowserTest2.rar

 

终于弄清楚了,.Net 1.0时代 非UI线程可以直接 操作UI控件

到了.NET 2.0开始 就不能直接操作UI控件了,

但是WebBrowser属于系统COM组件,.Net团队没有添加,检查操作线程机制。

但是实质上,也应该存在此类问题,只是他内部没有做检测罢了。

 

 

复制代码
using System;
using System.Threading;
using System.Windows.Forms;

namespace WebBrowserTest
{
    public partial class MainForm : Form
    {
        public MainForm()
        {
            InitializeComponent();
        }

        private Form childForm;
        private WebBrowser webBrowser;

        private void MainForm_Load(object sender, EventArgs e)
        {
            this.Text = string.Format("线程ID:{0}", Thread.CurrentThread.ManagedThreadId);
        }

        private void button1_Click(object sender, EventArgs e)
        {
            Thread thread = new Thread(new ThreadStart(this.CreateForm));
            thread.SetApartmentState(ApartmentState.STA);
            thread.IsBackground = true;
            thread.Start();
        }

        private void CreateForm()
        {
            this.childForm = new Form();

            this.webBrowser = new WebBrowser();
            this.webBrowser.Dock = DockStyle.Fill;
            this.webBrowser.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(this.webBrowser_DocumentCompleted);

            this.childForm.Controls.Add(this.webBrowser);

            //this.webBrowser.Navigate("http://tieba.baidu.com/"); //这里不是UI线程,为什么也能导航呢?

            this.childForm.ShowDialog();
        }

        private void button2_Click(object sender, EventArgs e)
        {
            if (this.childForm != null && this.childForm.IsHandleCreated)
            {
                //如果不调用childForm窗口的Invoke方法修改标题,就报异常!
                //线程间操作无效: 从不是创建控件“ChildForm”的线程访问它。

                int threadId = Thread.CurrentThread.ManagedThreadId;

                this.childForm.Invoke(new MethodInvoker(delegate
                {
                    this.childForm.Text = string.Format("主线程ID:{0}  子线程ID:{1}", threadId, Thread.CurrentThread.ManagedThreadId);
                    //这样修改是正常的。
                }));

                //this.childForm.Text = "修改标题"; //这样修改就报异常了!

                //为什么这里就能正常导航页面呢?
                //难道WebBrowser控件,始终都在UI线程运行?
                //即使创建它的线程,不是UI线程?

                this.webBrowser.Navigate("http://www.baidu.com/");
            }
        }

        private void webBrowser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
        {
            if (this.webBrowser.ReadyState == WebBrowserReadyState.Complete)
            {
                MessageBox.Show(string.Format("WebBrowser线程ID:{0}", Thread.CurrentThread.ManagedThreadId));
            }
        }
    }
}
复制代码

 

 转自:http://www.cnblogs.com/kofip/archive/2012/09/24/2699477.html

转载于:https://www.cnblogs.com/Ruiky/archive/2012/09/25/2701623.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值