Vb.net System.UnauthorizedAccessException仅使用多线程
我编写了一个代码来解析一些Web表 我使用Internet Explorer将一些web表放入Vb.net System.UnauthorizedAccessException仅使用多线程,vb.net,multithreading,runtime-error,Vb.net,Multithreading,Runtime Error,我编写了一个代码来解析一些Web表 我使用Internet Explorer将一些web表放入IHTMlementCollection,并使用以下代码: TabWeb = IE.document.getelementsbytagname("table") 然后我使用一个子对象,该子对象获取一个包含IHTMLElementCollection和一些其他数据的对象: Private Sub TblParsing(ByVal ArrVal() As Object) Dim WTab As m
IHTMlementCollection
,并使用以下代码:
TabWeb = IE.document.getelementsbytagname("table")
然后我使用一个子对象,该子对象获取一个包含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
我的目标是在sub执行解析时导航到另一个网页
我想澄清:
1) 我曾尝试将整个HTML发送到sub并将其放入webbrowser
,但没有成功,因为无法从System.Windows.Forms.HtmlElementCollection
转换到mshtml.IHTMLElementCollection
(或者我没能做到)
2) 我不能使用WebRequest
和类似的工具:我被迫使用InternetExplorer
3) 我不能使用System.Windows.Forms.HtmlElementCollection
,因为我的解析代码使用了不可用的单元格
、行
等等(我不想重写所有解析代码)
编辑:
好的,我使用回答提示修改了代码,如下所示:
'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_Body
字符串,它会在网页中抛出错误(它显示一个弹出窗口,我可以忽略错误)
我是否使用正确的方法将Html
从internetexplorer
获取到字符串中
编辑2:
我将代码更改为:
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")
但我得到一个错误弹出窗口,如(我试图翻译它):
标题:
网页错误
正文:
调试此页面?
此页面包含可能妨碍正确显示或正常运行的错误。
如果您没有测试网页,请单击“否”
两个复选框
不再显示此消息
使用内置Internet Explorer的脚本调试器
这与我试图将Html文本导入WebBrowser时遇到的错误相同。
但是,如果我可以忽略这个错误,我认为代码可以工作
当pop显示时,我在
Dim domDoc As New mshtml.HTMLDocument
翻译的错误文本为:
由于以下错误,检索CLSID为{25336920-03F9-11CF-8FD0-00AA00686F13}的组件的COM类工厂失败:第8001010条消息筛选器指示应用程序正忙。(HRESULT的异常:0x8001010A(RPC_E_SERVERCALL_RETRYLATER))
请注意,我已经设置了IE.silent=True
编辑:对于OP所指的“Internet Explorer”的含义存在混淆。我最初认为它是指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
结束编辑
以下是基于我以上的评论。您可以使用创建mshtml.HTMLDocument
如果要使用字符串处理工具操纵WebBrowser控件中显示的HTML页面的内容,请使用此属性
一旦将此属性提取为字符串,就不会连接到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)
您不能从后台线程与uicontrol进行交互,您应该在将数据发送到后台线程之前将数据与uicontrol分开,或者在获取请求之前检查每个UI控件是否需要InvokeRequiredvalues@Icepickle我认为传递“for value”意味着保护变量的内容。因此,我认为在线程执行其任务时,可以打开另一个网页。这是错的吗?我该怎么做呢?当你调用线程时,你实际上是在重定向吗?如果是,请尝试在不更改的情况下保持页面已加载it@bdn02但我的目标只是导航到另一个网页!这是你老问题的延伸吗,你可以更新旧的。我们接近解决方案了!请参阅我的编辑,但请注意:我使用的是Internet Explorer
而不是WebBrowser
。这会给我带来错误,但如果我在弹出窗口中选中“忽略”,代码似乎可以工作。如何将代码设置为自动忽略?(见我的编辑2)@genespos,这段代码保护您免受您最初发布的多线程问题的影响。该代码在发布之前经过测试,并在您向其传递有效的html文档源字符串的情况下运行。我还向您展示了如何从文档中获取html源代码。然而,这假设您首先有一个有效的文档,这是一个完全不同的问题。IE浏览器可以弹出几个不同的对话框,处理这些对话框的方法在对话框上有所不同,应该是一个单独的问题。使用以下url测试代码:“”错误(我认为)出现在我不感兴趣的脚本上。我唯一的问题是避免运行时错误:我只想忽略这些错误,代码就会工作!你能帮我做这件事吗?你没有解决我所有的问题,但你是唯一一个试图帮助我的人,所以我给了你奖金;)