gpt4 book ai didi

c# - 从另一个线程在 webbrowser 中加载大型 html 文件

转载 作者:太空宇宙 更新时间:2023-11-03 14:00:51 24 4
gpt4 key购买 nike

我正在设计一个小型应用程序,到目前为止,我很幸运能够保持我的线程简单高效,因此 ui 是响应式的。

现在我面临一个问题,我需要在选项卡式 Web 浏览器控件中加载大型本地 html 文件。这些页面的加载卡住了用户界面。我已经看到很多线程在另一个线程中谈论网络浏览器,但所有这些线程似乎都将网络浏览器排除在主用户界面之外。

我似乎无法让它正常工作。我尝试将 html 文件作为内存流加载到另一个线程中,然后将其提供给网络浏览器,我尝试在另一个线程中创建网络浏览器,但由于经典的线程间异常而关闭,尝试了 SupendLayout...

现在,我知道线程规则规定不能将在另一个线程中创建的控件添加到其他线程中的控件...我的问题很简单,有没有办法加载一个在显示的网络浏览器中显示大的 html 文件而不卡住用户界面?

如果这不是解决我的问题所必需的,则无需成为与线程相关的答案,但这是我最后一次尝试:

    public void openHtml(string input, bool isHtml = true, string tabTitle = "")
{
if (!this.loading)
{
this.loading = true;

ManualResetEvent resetEvent = new ManualResetEvent(false);
Panel panel = new Panel();
TabPage tab = new TabPage();
WebBrowser browser = null;

Thread t = new Thread(() =>
{
browser = new WebBrowser();
browser.CreateControl();
browser.SuspendLayout();

resetEvent.Set();

if (isHtml)
browser.DocumentText = input;
else
browser.Navigate(input);

Application.Run();
});

t.IsBackground = true;
t.SetApartmentState(ApartmentState.STA);
t.Start();

resetEvent.WaitOne();

panel.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;
panel.Controls.Add(browser);
panel.Dock = DockStyle.Fill;

browser.ObjectForScripting = new JsScriptInterface(this, browser);
browser.Dock = DockStyle.Fill;

tab.Controls.Add(panel);
tab.Text = tabTitle;

this.tabs.TabPages.Add(tab);
}
}

任何帮助将不胜感激。谢谢

最佳答案

我过去遇到过类似的问题,可以告诉您没有“真正的”解决方案。如您所知,问题是 UI 代码必须使用相同的线程,而不太好的线程代码在您无法控制的控件中(即 WebBrowser)。除非有人用适当的线程编写了更好的 WebBrowser 控件,不会挂起 UI(不太可能),否则我们不会有一个很棒的解决方案。

也就是说,有 2 个选项可能适合您 - 我只对它们进行了一些尝试,还没有分配时间让它们进入生产状态。所以也许认为这是一个部分解决方案:/

  1. 在您的控件中托管非 UI 线程控件(ab)。
  2. 渲染离屏和交换

在选项 1 中,链接讨论了将外部应用程序或来自另一个 AppDomain 的 WinForms 代码托管到您的应用程序/AppDomain 中。虽然我无法为您提供执行此操作所需的(复杂的?)代码,但我确实看到您可以在不同的线程(甚至可能在不同的 AppDomain 中)上拥有 WebBrowser 控件,然后使用所描述的技术在这些链接中显示此控件,就好像它在您的控件中一样。 WebBrowser 实际上不会在您的表单上,而是您表单的一个区域会有一个覆盖层,该覆盖层会随之调整大小/移动。我已经使用它成功地在 WinForms 应用程序中托管 Notepad++,调整大小有点笨拙但非常有用。您可以先尝试在普通 IE (iexplore.exe) 中呈现您的 HTML 文件,然后在您的应用程序中托管该应用程序,一旦您开始工作,请尝试使用更可控的 ActiveX 包装器控件 (WebBrowser)。

选项 2 对我来说使用 RichTextBox 效果很好,但我无法让 WebBrowser 以同样的成功响应。我所做的是生成一个带有 RichTextBox 的隐藏表单控件,加载我的数据并让它呈现。在我的主要可见表单上,我显示了另一个 RichTextBox,上面写着“正在加载...”或类似的内容。当 bg RichTextBox 完成时,我会将 Rtf 字段的内容移动到显示的控件中,它会在眨眼间呈现。可悲的是,WebBrowser 没有对其内部数据(即 DOM)公开相同级别的控制,但您可能能够比我能够更深入地研究使用 mshtml(cd)。

祝你好运!

关于c# - 从另一个线程在 webbrowser 中加载大型 html 文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10747083/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com