带有 WebBrowser.IsBusy 或 ReadyState (VB .NET) 的 InvalidCastException [英] InvalidCastException with WebBrowser.IsBusy or ReadyState (VB .NET)

查看:18
本文介绍了带有 WebBrowser.IsBusy 或 ReadyState (VB .NET) 的 InvalidCastException的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用建议作为我的另一个问题的答案的方法(自动化网站登录和表单填写?),并注意到一些奇怪的事情.

I was playing around with the method that was suggested as an answer to another of my questions (Automate website log-in and form filling?), and noticed something curious.

上述问题的答案是使用一系列 javascript 调用作为 URL 以填写网络表单并提交.我一直在尝试在 VB .NET 程序中自动执行此操作,但没有成功.

The answer to the above question was to use a series of javascript calls as URL's in order to fill in a web form and submit it. I have been trying to do this automatically inside a VB .NET program with no success.

我给出的原始示例不起作用,大概是因为您正在等待与 WebBrowser 控件正在工作的线程相同的线程:

The original example I was given doesn't work, presumably because you are waiting on the same thread as that in which the WebBrowser control is working:

WebBrowser1.Navigate("http://www.google.com")
Do While WebBrowser1.IsBusy OrElse WebBrowser1.ReadyState <> WebBrowserReadyState.Complete
    Threading.Thread.Sleep(1000)
Application.DoEvents()
Loop
WebBrowser1.Navigate("javascript:function%20f(){document.forms[0]['q'].value='stackoverflow';}f();")
Threading.Thread.Sleep(2000) 'wait for javascript to run
WebBrowser1.Navigate("javascript:document.forms[0].submit()")
Threading.Thread.Sleep(2000) 'wait for javascript to run

当然,如果您根本不等待,它也不起作用.您最初浏览的 URL 被中断.但有趣的是,您也无法立即对 javascript 调用执行导航".

If you don't wait at all, it doesn't work either, of course. The URL you originally browse to is interrupted. But interestingly, you cannot perform the "navigations" to the javascript calls without delay, either.

所以我尝试了另外两种方法:使用 DocumentCompleted 事件等待浏览器完成加载页面之前浏览到嵌套 URL.不幸的是,DocumentCompleted 并不总是触发,并且似乎不会在每个 javascript URL 之后触发.

So I've tried two other methods: using the DocumentCompleted event to wait to browse to the nest URL until the browser has finished loading the page. Unfortunately, DocumentCompleted does not always fire, and doesn't seem to fire after each javascript URL.

我尝试的第二种方法是将等待放在一个单独的线程中:

The second method I tried was to put the wait in a separate thread:

 Private Delegate Sub SetTextDelegate(ByVal TheText As String)
 Private Sub delSetText(ByVal TheText As String)
     WebBrowser1.Navigate(TheText)
 End Sub

 Private Sub BrowseTo(ByVal URL As String)
     If WebBrowser1.InvokeRequired Then
         Me.BeginInvoke(New SetTextDelegate(AddressOf delSetText), URL)
     Else
         WebBrowser1.Navigate(URL)
     End If
 End Sub

 Private Sub TargetURL()
   BrowseTo("http://www.google.com")
 End Sub

 Private Sub TypeSomethingIn()
     BrowseTo("javascript:function%20f(){document.forms[0]['g'].value='test';}f();")
 End Sub

 Private Sub SubmitForm()
     BrowseTo("javascript:document.forms[0].submit()")
 End Sub

 Private Sub Wait()
     While True
         If WebBrowser1.ReadyState = WebBrowserReadyState.Complete Then Exit Sub
         Threading.Thread.Sleep(100)
     End While
 End Sub

 Private Sub AutoBrowse()
     TargetURL()
     Wait()
     TypeSomethingIn()
     Wait()
     SubmitForm()
 End Sub

 Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
     Dim t As Threading.Thread
     t = New Threading.Thread(AddressOf AutoBrowse)
     t.Start()
 End Sub

奇怪的是,在等待循环中检查 ReadyState(或 IsBusy,就此而言)有时会抛出 InvalidCastException.据推测,对这些的调用不是线程安全的?我不知道.如果我将违规调用放在 Try 块中,则等待循环将无法正常工作.事实上,似乎异常仍然存在"把一切搞砸了,因为即使使用 try 块单步执行代码,Visual Studio 也会冻结 10 到 20 秒(没有 try 块也一样).

The curious thing is that the check of ReadyState (or IsBusy, for that matter) in the wait loop will sometimes throw a InvalidCastException. Presumably calls to these are not thread safe? I have no idea. If I put the offending call inside a Try block, the wait loop just fails to work. In fact, it even seems the exception "persists" to screw everything up, because even stepping through the code with the try block Visual Studio freezes for a good 10 to 20 seconds (it does the same without the try block).

有什么想法吗?

推荐答案

我经历过的最有趣的问题之一,对我来说无法在 inet 中找到解决方案 - 问题是否与网页浏览器控件.问题是当我试图访问WebBrowser 控件实例的文档属性,我得到无效的强制转换异常".问题是 WebBrowser 控件是设计为在一个线程中工作.所以要解决这个问题,你必须只检查InvokeRequired 属性,如果它的值为真,则调用逻辑来自委托,提供给 browser.Invoke(...) 方法.

One of the most interesting issues I had experienced and which for I was not able to find a solution in inet - was problem related to WebBrowser control. The thing is that when I was trying to access the Document property of the WebBrowser control instance, I was getting "Invalid cast exception". The thing is that the WebBrowser control is designed to work in one thread. So to fix this you must only check the InvokeRequired property and if it's value is true, then call the logic from the delegate, given into browser.Invoke(...) method.

来源

这篇关于带有 WebBrowser.IsBusy 或 ReadyState (VB .NET) 的 InvalidCastException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆