【发布时间】:2017-02-16 20:17:02
【问题描述】:
我在多个线程中使用 WebBrowser,但是,在一些执行(从 50 到 10000+)之后,我得到了访问冲突异常。
相关部分代码:
开始线程:
var thread = new Thread(() =>
{
ProcessingThread();
});
thread.SetApartmentState(ApartmentState.STA);
thread.Start();
处理线程:
void ProcessingThread()
{
WebBrowser webBrowser = new WebBrowser();
webBrowser.ScriptErrorsSuppressed = true;
while (!Shutdown)
{
string htmlstring = GetHTMLString();
webBrowser.DocumentText = htmlstring;
webBrowser.Document.OpenNew(true);
webBrowser.Document.Write(htmlstring);
webBrowser.Refresh();
HtmlDocument doc = webBrowser.Document;
//Do Work
}
}
通常有 2 到 8 个这样的线程同时运行。
我经常遇到访问冲突
webBrowser.Document.OpenNew(true);
我已经阅读了许多类似的问题,但找不到我的问题的解决方案。
我想弄清楚异常的原因和解决方法。
到目前为止,我正在使用 WinForms 和 Visual Studio 2015 Update 3。
异常字符串:
抛出异常:“System.AccessViolationException”在 System.Windows.Forms.dll
我注意到的另一件事是,我使用的 .NET 版本越高,上面的线程在抛出异常之前设法执行的次数就越少。
例如,从我尝试运行它的十次开始,它在 .NET 4.5 上执行 1000 到 10000 次(我所做的所有测试的绝对最大值,通常最大值约为 5000 次),在 .NET 4.5 上执行 70 到 1500 次。 NET 4.6.1。
我试过了:
- 使用本机代码调试选项,但仍指相同 线。
- 更改平台目标而没有任何明显的结果。目前,它是 x86。
- 打开和关闭代码优化。
- 在没有调试器的情况下运行。
- 将目标框架更改为无结果。目前是 .NET 4.5.2。
- 在另一台机器上运行/调试应用程序。
我也知道 WebRequest、WebClient 和另外关于 HMTLAgilityPack,但我使用 WebBrowser 来支持它的 Javascript。
【问题讨论】:
-
愚蠢的问题:为什么你需要在不同的线程中使用 2-8 个浏览器?我真的很好奇。
-
@FrancisLord,正在解析 HTML。其中一些使用 JavaScript 生成必要的数据,而使用 WebBrowser 是我能想到的获取数据的唯一方法。当然,我可以尝试使用不同的浏览器(例如 awesomium),但除非在此任务中必要,否则我真的不想使用 3rd 方工具,而且我真的很想知道当前访问冲突异常有什么问题。也应该可以在表单上放置多个 WebBrowser 并使用它们 - 但我认为这可能比我现在所做的更糟糕。
-
您是否尝试将线程设置为 MTA 而不是 STA?
-
根据我在网上快速搜索的内容,这基本上应该是您破坏了线程的一些 COM 合同,或者来自非托管代码中的访问冲突(您对此无能为力)跨度>
-
您可能想看看这里所说的内容,这可能会对您有所帮助:stackoverflow.com/a/4156000/4064630。 TLDR:将线程设置为 STA 意味着您必须遵守 COM+ 设置的一些规则,否则,我相信您会得到 AccessViolation。那个或 WebBrowser 在非托管代码中引发错误,在 .net 中作为 AccessViolation 冒泡
标签: c# multithreading exception webbrowser-control access-violation