Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 将Webbrowser与Control.invoke一起使用_C#_Browser_Backgroundworker_Invoke - Fatal编程技术网

C# 将Webbrowser与Control.invoke一起使用

C# 将Webbrowser与Control.invoke一起使用,c#,browser,backgroundworker,invoke,C#,Browser,Backgroundworker,Invoke,我正在开发一个用于web抓取的windows应用程序。为此,我使用Webbrowser控件-我不能使用webrequest/webclient/webresponse类,因为网页是使用javascript动态加载的。 该应用程序运行良好,但由于我进行了大量处理,它会不必要地加载UI。我断断续续地收到“没有响应”的消息。所以我所做的是: 1.在UI线程上创建webbrowser 2.将长时间运行的进程放在后台线程上 3.每当我需要获取页面文档时,我都使用Control.Invoke 4.通过调

我正在开发一个用于web抓取的windows应用程序。为此,我使用Webbrowser控件-我不能使用webrequest/webclient/webresponse类,因为网页是使用javascript动态加载的。
该应用程序运行良好,但由于我进行了大量处理,它会不必要地加载UI。我断断续续地收到“没有响应”的消息。所以我所做的是:

1.在UI线程上创建webbrowser
2.将长时间运行的进程放在后台线程上
3.每当我需要获取页面文档时,我都使用Control.Invoke
4.通过调用后台线程返回页面的文档

在回调函数中,我可以看到页面的文档被很好地提取出来。但是,返回给后台工作程序的文档(HtmlDocument)未正确计算。当我逐步通过调试器时,我得到“函数求值超时消息…”。我一直在使用语法,不断得到无效的强制转换异常或跨线程消息传递异常
下面是我如何编写回调/委托的代码:


现在来看后台工作程序中处理“返回的”HTMLDocument的代码:



遇到调试器消息:“由于上一个函数求值超时,函数求值被禁用。必须继续执行才能重新启用函数求值。”。这是解决这个问题的正确方法吗?正如我所说,我无法通过webrequest等获取javascript内容,我也无法在UI上运行htmldocument解析,因为这会导致糟糕的用户体验。此外,我还需要创建几个webbrowser实例。如果这不是最好的方式,我也会向其他图书馆开放。谢谢。

我建议使用HtmlAgilityPack。这是专门为网页“抓取”而设计的


发生这种情况是因为您在工作线程或调试器线程中调用的WebBrowser方法实际上没有在该线程上运行。WebBrowser是一个单元线程COM组件,COM自动将工作线程的调用封送回UI线程。这在调试器中不起作用,因为UI线程被调试器冻结


对此您无能为力,实际上,在UI线程上运行这些调用仍然会导致UI冻结。解决这个问题的唯一方法是完全在自己的STA线程上运行浏览器。你不能看,我想这不应该是个问题。检查您需要的代码。

否它不运行javascript。但是你可以用它来运行javascript。实际上,我在使用webbrowser之前使用了htmlagility包。我特别喜欢使用xpath提取元素的方式。我的表单将脚本(我相信是jquery)存储在一个.js文件中。因此javascript调用是“不可见的”。在这种情况下jint.codeplex能工作吗?它工作了!!你帮我省了几个小时的无目的调试。我认为重要的部分是将公寓状态设置为STA。非常感谢:)
private delegate HtmlDocument RefreshDelegate(); 
private HtmlDocument RefreshBrowser()
    {
        WebBrowser br1 = ((WebBrowser)this.Controls["br1"]); //get webbrowser, "br1"
        br1.Refresh(); //refresh browser
        return br1.Document; //is retrieved correctly
   }
WebBrowser br1 = ((WebBrowser)this.Controls["br1"]); //get the browser
HtmlDocument document = (HtmlDocument)br1.Invoke(new RefreshDelegate(this.RefreshBrowser));  //not evaluated 
//do stuff with document