跨线程操作WebBrowser的麻烦“指定的转换无效”

起因:程序原来是定时5分钟监测一个网页A,并进行相应处理C,后来要加入对另一个网页B的监测,而新网页B是flash,flash定时10秒刷新数据,原来的处理流程C没问题,但发现过一段时间后,网页B停止了更新数据相应,经过分析发现是处理流程C阻塞了网页B的响应,于是便考虑处理流程C放到子线程里,而处理流程C需要访问网页A,从而抛出了错误“在某个线程上创建的控件不能成为在另一个线程上创建的控件的父级”、“指定的转换无效。”

网上搜索,比较有用及简单明了的有:

解决多线程操作控件时可能出现的异常:“在某个线程上创建的控件不能成为在另一个线程上创建的控件的父级”

winform跨线程操作webBrowser控件

使用VB.NET开发多线程

c#_在多线程下访问WebBrowser对象报异常,"指定的转换无效。" 这个帖子还有大伽18楼微软MVP蒋晟 说:“ Windows Forms控件不支持跨线程调用,IE的很多接口也不支持。 ” 23楼绿色夹克衫 :其他线程调用WebBrowser的话应该还是需要Invoke给创建的线程,另外创建线程也需要是STA的。从微软自己的实现来看,用多进程似乎更好一些,需要自己写一下进程通讯。 

后来发现是可以跨线程访问的,既没有某些帖子说的不能用Threading.Timer定时器,也不会说不能访问“注:这里的WebBrowser要从代码中new,如果是拉控件的方式创建的,将会报错:"指定的转换无效"”的问题,现将前人经验整理,方便自己查阅。

Imports System.Threading 
Public Class Form1 
    '//子线程里调用UI线程执行InvokeFun() 
    '访问WebBrowser控件抛出错误: 
    'System.InvalidCastException:“指定的转换无效。” 
    'HResult = 0x80004002 
    '访问TextBox控件抛出错误: 
    'System.InvalidOperationException:“线程间操作无效: 从不是创建控件“TextBox1”的线程访问它。” 
    'HResult = 0x80131509 

    '//1、设置子线程函数 
    Private Sub ThreadFun() 
        'MethodInvoker不带参数 
        Dim test As MethodInvoker = New MethodInvoker(AddressOf InvokeFun)  '通过委托执行 
        Me.Invoke(test)         '同步 
        'Me.BeginInvoke(test)   '也可以用异步执行指定的委托 
    End Sub 

    '//2、设置UI线程里要执行的函数 
    Private Sub InvokeFun() 
        TextBox1.Text = Now 
        MsgBox(WebBrowser1.Document.All.Count) 
    End Sub 
    '//3、调用子线程 
    '可以使用线程定时器启动子线程 
    Dim ThreadingTimer1 As Threading.Timer = New Threading.Timer(New TimerCallback(AddressOf ThreadFun), Nothing, 6000, 6000) 
    '可以通过按钮启动子线程 
    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click 
        Dim thdProcess As Thread = New Thread(New ThreadStart(AddressOf InvokeDeThreadFun)) 
        thdProcess.Start() 
    End Sub 

    '用Delegate可以带参数 
    Private Delegate Sub DeThreadFun() 
    Private Sub InvokeDeThreadFun() 
        Dim useDeThreadFun As DeThreadFun = New DeThreadFun(AddressOf InvokeFun) 
        Me.Invoke(useDeThreadFun) 
    End Sub 
    '带参数 
    Private Sub ThreadFun2() 
        Dim Tasks As New TasksClass() 
        Tasks.wb = WebBrowser1 

        Dim test As MethodInvoker = New MethodInvoker(AddressOf Tasks.SomeTask) 

        Me.Invoke(test) 
    End Sub 

    '需要传递参数,则封装到Class里 
    Class TasksClass 
        Friend wb As WebBrowser 
        Sub SomeTask() 

            MsgBox(wb.Document.All.Count) 

        End Sub 
    End Class 


End Class 

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值