【转载】c#多线程使用webbrowser控件
2010-11-25 14:42
519 查看
本来打算在完成事件中分析页面的,可是郁闷了半天,根本就没有完成处理函数的调用,搜索得到解决,在此感谢原文作者http://www.soaspx.com/dotnet/csharp/csharp_20100315_3210.html
我们在做采集软件的时候有些网站通过直接分析html文本是很麻烦的事情在利用WinForm编程的情况下有一种更好的方式当然是分析HtmlDocument然而,这HtmlDoucment并不能直接创建它必须由 WebBroswer控件Navigate生成一个页面后才能取得wb.HtmlDocument然后就可以对HtmlDocument的各元素、标签进行分析。事实上,在采集的时候并不是采集只会采集单个页面这样的话,在主窗体中就可以完成譬如采集一些列表页面,有N多个页那么,一个循环下去,用WebBrowser去响应,那就会导致假死这时候,我们肯定会想到用多线程去做这件事情C#的多线程,大家应该都知道,有STA,MTA两种模式然而,WebBrowser控件却有一个不好的特点那就是:它只支持多线程STA模式例如下面的代码,
需要分析WebBrowser产生 的HtmlDocument时,必须在事件DocumentCompleted里面去操作只有这时候,WebBrowser才算加载完成不过,这只是一个陷阱!!!!WebBrowser有一个特性,那就是在多线程STA的时候,根本就不等到DocumentCompleted的执行也就是无法再进行后面的操作!!!这样的话,我们该如何办呢?也许有人会想:wb.Document.Write(string)方法,如下:
代码
但这时候,我们会发现,wb.DocumentText总是没有的当时我也很郁闷,搜索园子里的文章与MSDN,都是可以用DocumentText赋值的但也在网上发现了很多说操作后没有结果的经过努力搜索在园子里发现了一篇有用的文章里提到的一个例子经过测试后发现WebBrowser必须经过Navigate后才会产生Document于是忽,终于可以实现了多线程下面的操作了最终代码如下
代码
当然,在线程里面处理每个结点与数据库操作的时候,可以用ThreadPool这样效果与性能可能好一些最后说一下我自己对这个的一点改进建议,在处理含有中文字符的网页是,上面给的那个GetHtmlSource(string Url)
拿回来的数据可能会乱码,我是用webclent 来下载的,设置合适的字符集就没有乱码了,
我们在做采集软件的时候有些网站通过直接分析html文本是很麻烦的事情在利用WinForm编程的情况下有一种更好的方式当然是分析HtmlDocument然而,这HtmlDoucment并不能直接创建它必须由 WebBroswer控件Navigate生成一个页面后才能取得wb.HtmlDocument然后就可以对HtmlDocument的各元素、标签进行分析。事实上,在采集的时候并不是采集只会采集单个页面这样的话,在主窗体中就可以完成譬如采集一些列表页面,有N多个页那么,一个循环下去,用WebBrowser去响应,那就会导致假死这时候,我们肯定会想到用多线程去做这件事情C#的多线程,大家应该都知道,有STA,MTA两种模式然而,WebBrowser控件却有一个不好的特点那就是:它只支持多线程STA模式例如下面的代码,
Thread tread = new Thread(new ParameterizedThreadStart(BeginCatch)); tread.SetApartmentState(ApartmentState.STA); tread.Start(url); 代码 private void BeginCatch(object obj) { string url = obj.ToString(); WebBrowser wb = new WebBrowser(); wb.ScriptErrorsSuppressed = true; wb.Navigate(url); wb.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(wb_DocumentCompleted); }
需要分析WebBrowser产生 的HtmlDocument时,必须在事件DocumentCompleted里面去操作只有这时候,WebBrowser才算加载完成不过,这只是一个陷阱!!!!WebBrowser有一个特性,那就是在多线程STA的时候,根本就不等到DocumentCompleted的执行也就是无法再进行后面的操作!!!这样的话,我们该如何办呢?也许有人会想:wb.Document.Write(string)方法,如下:
代码
private void BeginCatch(object obj) { string url = obj.ToString(); WebBrowser wb = new WebBrowser(); wb.ScriptErrorsSuppressed = true; string htmlcode = GetHtmlSource(url); wb.Document.Write(htmlcode); //执行分析操作 } //WebClient取网页源码 private string GetHtmlSource(string Url) { string text1 = ""; try { System.Net.WebClient wc = new WebClient(); text1 = wc.DownloadString(Url); } catch (Exception exception1) {} return text1; }
但这时候,我们会发现,wb.DocumentText总是没有的当时我也很郁闷,搜索园子里的文章与MSDN,都是可以用DocumentText赋值的但也在网上发现了很多说操作后没有结果的经过努力搜索在园子里发现了一篇有用的文章里提到的一个例子经过测试后发现WebBrowser必须经过Navigate后才会产生Document于是忽,终于可以实现了多线程下面的操作了最终代码如下
代码
private void ThreadWebBrowser(string url) { Thread tread = new Thread(new ParameterizedThreadStart(BeginCatch)); tread.SetApartmentState(ApartmentState.STA); tread.Start(url); } private void BeginCatch(object obj) { string url = obj.ToString(); WebBrowser wb = new WebBrowser(); wb.ScriptErrorsSuppressed = true; //在这里Navigate一个空白页面 wb.Navigate("about:blank"); string htmlcode = GetHtmlSource(url); wb.Document.Write(htmlcode); //执行分析操作 ……(略) } //WebClient取网页源码 private string GetHtmlSource(string Url) { string text1 = ""; try { System.Net.WebClient wc = new WebClient(); text1 = wc.DownloadString(Url); } catch (Exception exception1) {} return text1; }
当然,在线程里面处理每个结点与数据库操作的时候,可以用ThreadPool这样效果与性能可能好一些最后说一下我自己对这个的一点改进建议,在处理含有中文字符的网页是,上面给的那个GetHtmlSource(string Url)
拿回来的数据可能会乱码,我是用webclent 来下载的,设置合适的字符集就没有乱码了,
相关文章推荐
- [转载]C#中的WebBrowser控件的使用
- C# winform使用webbrowser控件,不弹出新的页面,只在当前窗口打开
- C# webBrowser控件使用心得
- C#:WebBrowser控件的使用教程及相关问题整理
- C# WebBrowser控件使用整理
- C#中用Invoke调用控件方法和BeginInvoke线程使用方法
- C#中用Invoke调用控件方法和BeginInvoke线程使用方法
- C#中的WebBrowser控件的使用
- C# 使用SuperMap控件需要千万注意的地方(转载)
- C#中的WebBrowser控件的使用
- C#使用 webBrowser 控件总结
- C#WebBrowser控件使用教程与技巧收集
- C#中的WebBrowser控件的使用
- c#中使用多线程访问winform中控件的若干问题 解决线程间操作无效: 从不是创建控件的线程访问它
- c#利用委托跨线程调用UI控件完整使用方法
- c#中Invoke使用方法(线程间操作无效: 从不是创建控件的线程访问它。那么创建它的线程是哪个线程?)
- C#中的WebBrowser控件的使用
- C# 使用SerialPort控件用类及线程实现串口通信
- C# webBrowser控件使用心得
- C#中的WebBrowser控件的使用