多线程存取WinForm控件

采集器使用的是System.Windows.Forms.WebBrowser, 在constructor里面添加了DocumentChanged的event handler, 来模拟浏览器访问webmaster的流程, 访问external-links页面时便修改constructor传进来的LinkProfile

在主线程里是new WebmasterScarper(website, link_profile)之后接着就new LinkProfileTemplate(link_profile)

本来以为采集器应该走完流程才创建LinkProfileTemplate, 但是发现创建的LinkProfileTemplate是空图表, Debug时又发现new LinkProfileTemplate() 比 WebBrowser.DocumentChanged的event handler更早执行, 现在才想起来event handler可能是单独一个线程?


接着在new LinkProfileTemplate()之间加了循环检测: 如果link_profile为空就使进程sleep 1秒, 然后继续检测, Debug发现这个循环一直没有停止, 而且DocumentChanged的event handler一直没有被调用

这时候想 他们可能是在同一个线程?


接着给采集器单独建了一个线程执行, browser.Navigate()处出现了异常{"Unable to get the window handle for the 'WebBrowser' control. Windowless ActiveX controls are not supported."},  InnerException是{"Cross-thread operation not valid: Control '' accessed from a thread other than the thread it was created on."} 

确实创建的线程和存取的线程不是同一个线程:

WebmasterScraper scraper = new WebmasterScraper(website, link_profile);

new Thread(scraper.start).Start();

这么说WinForm的控件不是thread safe


按照这个方法来使用Control.Invoke():

http://www.perceler.com/articles1.php?art=crossthreads1

还是会出现同样的错误

然后把constructor的方法移到了start()中(bad smell..), 出现了另一个异常System.Threading.ThreadStateException: Could not instantiate ActiveX control 'GUID' because the current thread is not in a single-threaded apartment.


最后没办法只有把主线程的之后的代码都放到scraper中了..(powerless..)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值