我正在设计一个小型应用程序,到目前为止,我已经足够幸运地保持我的线程简单高效,因此ui响应迅速。从另一个线程在webbrowser中加载大型html文件
现在我遇到了一个问题,我需要在标签式浏览器控件中加载大型本地html文件。这些页面的加载冻结了用户界面。我已经看到很多线索都在讨论生活在另一个线程中的web浏览器,但它们都似乎使webbrowser远离主UI。
我似乎无法让它正常工作。我尝试加载另一个线程中的html文件作为内存流,然后将其提供给webbrowser,我试图在另一个线程中创建webbrowser,但与经典的线程异常关闭,试图SupendLayout ...
Now ,我知道的线程规则,指出你不能将另一个线程中创建的控件添加到某个其他线程的控件中......我的问题很简单,有没有什么办法可以加载一个大的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);
}
}
任何帮助将不胜感激。谢谢
你用t.SetApartmentState(ApartmentState.MTA)检查; ? –
是的,我收到一个错误,说它应该是STA,因为webbrowser是一个ActiveX控件。仍然没有快乐。 – ChG
渲染UI仅在主线程上。您可以在后台线程上创建HTML或FlowDocument或...但一旦它开始呈现您无法控制的回调。我所做的是检查大小,并提出一个消息框“你确定”。如果它是支持虚拟化的UI控件,那么一切都很好。不幸的是,浏览器控件不支持虚拟化。我所做的是,如果选项卡未激活,则不加载该选项卡。在MVVM下,它的工作原理是不同的。我希望你能得到更好的答案。 – Paparazzi