System.UnauthorizedAccessException仅使用多线程

时间:2016-01-19 07:42:36

标签: vb.net multithreading runtime-error

我编写了一个代码来解析一些Web表。

我使用带有以下代码的Internet Explorer将一些Web表格放入IHTMLElementCollection

TabWeb = IE.document.getelementsbytagname("table")

然后我使用一个sub获取包含IHTMLElementCollection的对象和其他一些数据:

Private Sub TblParsing(ByVal ArrVal() As Object)
    Dim WTab As mshtml.IHTMLElementCollection = ArrVal(0)
    'some code
End sub

我的问题是:如果我只是"打电话"这段代码,它可以正常工作:

Call TblParsing({WTab, LiRow})

但是,如果我尝试将它运行到线程池中:

ThreadPool.QueueUserWorkItem(New WaitCallback(AddressOf TblParsing), {WTab, LiRow})

代码失败并给我多个

  

System.UnauthorizedAccessException的

这发生在(每个)这些代码行上:

Rws = WTab(RifWT("Disc")).Rows.Length 

If Not IsError(WTab(6).Cells(1).innertext) Then
    Ogg_W = WTab(6).Cells(1).innertext

我的目标是在我的子执行解析时导航到另一个网页。

我想澄清一下:

1)我已尝试将整个HTML发送到子版并将其转换为webbrowser,但它无法正常工作,因为它无法从{{{{}}投射1}}到System.Windows.Forms.HtmlElementCollection(或者我无法做到);

2)我无法使用mshtml.IHTMLElementCollection和类似内容:我被迫使用WebRequest;

3)我无法使用InternetExplorer,因为我的解析代码使用System.Windows.Forms.HtmlElementCollectionCells等不可用(我不想重写)我所有的解析代码)

编辑:

好的,我使用如下的答案提示修改了我的代码:

Rows

我没有错误,但我不确定它是否可以,因为我尝试将'This in the caller sub Dim IE As Object = CreateObject("internetexplorer.application") '...some code Dim IE_Body As String = IE.document.body.innerhtml ThreadPool.QueueUserWorkItem(New WaitCallback(AddressOf TblParsing_2), {IE_Body, LiRow}) '...some code 'This is the called sub Private Sub TblParsing_2(ByVal ArrVal() As Object) Dim domDoc As New mshtml.HTMLDocument Dim domDoc2 As mshtml.IHTMLDocument2 = CType(domDoc, mshtml.IHTMLDocument2) domDoc2.write(ArrVal(0)) Dim body As mshtml.IHTMLElement2 = CType(domDoc2.body, mshtml.IHTMLElement2) Dim TabWeb As mshtml.IHTMLElementCollection = body.getElementsByTagName("TABLE") '...some code 字符串用于webbrowser并在网页中抛出错误(它显示了一个弹出窗口,我可以忽略错误)。

我是否使用正确的方式将IE_BodyHtml转换为Internet Explorer

EDIT2:

我将代码更改为:

string

但是我得到一个错误的PopUp(我试图翻译它):
标题:

  

网页错误

文字:

  

调试此页面?
  此页面包含可能妨碍正确显示或正常运行的错误   如果您没有测试网页,请单击否。

两个复选框

  

不再显示此消息
  使用脚本调试器内置Internet Explorer

我试图将Html文本导入WebBrowser时出现了同样的错误 但是,如果我可以忽略这个错误,我认为代码可以工作!

当pop显示我出错

Dim IE As New SHDocVw.InternetExplorer  
'... some code
Dim sourceIDoc3 As mshtml.IHTMLDocument3 = CType(IE.Document, mshtml.IHTMLDocument3)
Dim html As String = sourceIDoc3.documentElement.outerHTML
ThreadPool.QueueUserWorkItem(New WaitCallback(AddressOf TblParsing_2), {html, LiRow})
'... some code

Private Sub TblParsing_2(ByVal ArrVal() As Object)
    Dim domDoc As New mshtml.HTMLDocument
    Dim domDoc2 As mshtml.IHTMLDocument2 = CType(domDoc, mshtml.IHTMLDocument2)
    domDoc2.write(ArrVal(0))
    Dim body As mshtml.IHTMLElement2 = CType(domDoc2.body, mshtml.IHTMLElement2)
    Dim TabWeb As mshtml.IHTMLElementCollection = body.getElementsByTagName("TABLE")

翻译的错误文字是:

  

由于以下错误,检索具有CLSID {25336920-03F9-11CF-8FD0-00AA00686F13}的组件的COM类工厂失败:第8,001,010个消息过滤器指示应用程序正忙。 (来自HRESULT的异常:0x8001010A(RPC_E_SERVERCALL_RETRYLATER))。

请注意,我已设置Dim domDoc As New mshtml.HTMLDocument

1 个答案:

答案 0 :(得分:1)

编辑:对于“Internet Explorer”的OP含义存在疑惑。我最初认为它意味着WinForm Webbrowser控件;但OP正在直接创建COM浏览器,而不是使用.Net包装器。

要获取浏览器文档的定义HTML,您可以针对mshtml.IHTMLDocument3接口转换文档以公开documentElement属性。

Dim ie As New SHDocVw.InternetExplorer  ' Proj COM Ref: Microsoft Internet Controls
ie.Navigate("some url")
' ... other stuff
Dim sourceIDoc3 As mshtml.IHTMLDocument3 = CType(ie.Document, mshtml.IHTMLDocument3)
Dim html As String = sourceIDoc3.documentElement.outerHTML

结束编辑。

以下内容基于我的评论。您可以使用WebBrowser.DocumentText property创建mshtml.HTMLDocument

  

如果要使用字符串处理工具操作WebBrowser控件中显示的HTML页面的内容,请使用此属性。

一旦将此属性提取为String,就没有与WebBrowser控件的连接,您可以在任何所需的线程中处理数据。

Dim html As String = WebBrowser1.DocumentText

Dim domDoc As New mshtml.HTMLDocument
Dim domDoc2 As mshtml.IHTMLDocument2 = CType(domDoc, mshtml.IHTMLDocument2)
domDoc2.write(html)

Dim body As mshtml.IHTMLElement2 = CType(domDoc2.body, mshtml.IHTMLElement2)
Dim tables As mshtml.IHTMLElementCollection = body.getElementsByTagName("TABLE")

' ... do something

' cleanup COM objects
System.Runtime.InteropServices.Marshal.FinalReleaseComObject(body)
System.Runtime.InteropServices.Marshal.FinalReleaseComObject(tables)
System.Runtime.InteropServices.Marshal.FinalReleaseComObject(domDoc)
System.Runtime.InteropServices.Marshal.FinalReleaseComObject(domDoc2)