0

我在使用 webbrowser 控件正确显示 html 时遇到问题。我的目标是将自定义 html 添加到 webbrowser 控件,显示它,并将其屏幕截图保存为 png。目前我正在使用 Document.OpenNew 和 Document.Write(htmlText) 和 Application.DoEvents()。但是,由于我在后台线程中运行它,有时它会死锁。我知道罪魁祸首是 Application.DoEvents() 这给我带来了麻烦。

但是,如果我删除它并将 html 直接设置为 DocumentText 属性,我怎么知道它何时完全“渲染”或加载。我使用了 DocumentCompleted 事件,但这似乎不起作用,因为即使在事件触发后保存的图像仍然是空的。

我也有线程作为 STA。

这是现有的代码:

Thread th = new Thread(new ThreadStart(createImage));
th.SetApartmentState(ApartmentState.STA);
th.Start();
th.Join(TIMEOUT);

private void createImage() {
 var browser = new WebBrowser();
 var doc = browser.Document;
 doc.OpenNew(false);
 doc.Write("<html><body>....</body><html>)");
 //loop for few seconds
 for(int i=0; i<20; i++)
 {
   Application.DoEvents();
   Thread.Sleep(100);
 }
 //save to file as png.
}

这是我正在尝试的代码:

private void createImage() {
 var browser = new WebBrowser();
 bool docComplete = false;
 browser.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(
                (Object sender, WebBrowserDocumentCompletedEventArgs args) =>
                { docComplete = true; }
                );
 browser.DocumentText = "<html>.....";
 while (!_docComplete)
 {                    
    Thread.Sleep(100);
  }
 // save image
 // :-( not working
}
4

1 回答 1

0

您必须将线程创建为 STA,这只是在后台线程中运行 WebBrowser 的方式。

bw.SetApartmentState(ApartmentState.STA);

HtmlDocument.Write Method中没有关于等待的信息。如果还需要,那么您可以添加 DocumentCompleted 处理程序而不是 DoEvents

private void captureImageThread(string html) { 
   var thread = new Thread(() => { 
       var browser = new WebBrowser(); 
       browser.DocumentCompleted += browser_DocumentCompleted; 
       browser.DocumentText = html;
       Application.Run(); 
   }); 
   thread.SetApartmentState(ApartmentState.STA); 
   thread.Start(); 
} 

void browser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e) { 
   var br = sender as WebBrowser; 
   // save image here
   Application.ExitThread();   // Stops the thread 
} 
于 2012-10-16T15:13:42.417 回答