我正在設計一個小型應用程序,到目前爲止,我已經足夠幸運地保持我的線程簡單高效,因此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