【发布时间】:2011-02-28 01:59:42
【问题描述】:
我使用 WebBrowser 控件作为特殊类型标记的“预览”。我处理标记,然后设置浏览器的 DocumentText 属性以显示它。这工作正常。
但是,有时控制需要 5-10 秒以上才能完成此操作。由于我在应用程序启动时执行此操作(使用DocumentText = "" 关闭窗口),并且仍然需要很长时间才能执行此操作,所以我想以某种方式线程这个或其他东西,以便应用程序的其余部分可以在控制时启动.. . 做任何事情。
供参考,有问题的函数是:
private void btnRefresh_Click(object sender, EventArgs e) {
try {
scrolltop = html.Document.Body.ScrollTop;
scrollleft = html.Document.Body.ScrollLeft;
} catch (NullReferenceException) { }
html.DocumentText = HtmlProcessing.ProcessCode(txtCode.Text); //takes 5-10 seconds
}
我知道我不能只启动一个线程来处理这个问题,因为我假设如果我尝试从另一个线程访问它,WebBrowser 控件会呕吐。我可以使用其他任何技术来做到这一点吗?
编辑:
事实证明,我的延迟不是是由html.DocumentText 引起的,也不是由HtmlProcessing.ProcessCode 引起的,而是由我从示例中省略的一些代码引起的,因为我认为这无关紧要:
private void btnRefresh_Click(object sender, EventArgs e) {
try {
scrolltop = html.Document.Body.ScrollTop;
scrollleft = html.Document.Body.ScrollLeft;
} catch (NullReferenceException) { }
html.DocumentText = HtmlProcessing.ProcessCode(txtCode.Text, GetImageList());
}
对GetImageList() 的调用一直持续。函数内容如下:
List<string> GetImageList() {
List<string> ret = new List<string>();
ret.AddRange(Directory.GetFiles(settings.LocalImageFolder).Where((f) => { return extensions.Contains(Path.GetExtension(f)); }));
ret.AddRange(Directory.GetFiles(settings.RemoteImageFolder).Where((f) => { return extensions.Contains(Path.GetExtension(f)); }));
return ret;
}
而且,settings.RemoteImageFolder 实际上是一条永远占用的网络路径。我最终把它变成了IEnumerable<string>。这样,我只有在ProcessCode 确实需要那里的文件时才访问网络。
【问题讨论】:
-
你有没有分析过时间的确切去向?您可能会在不同的线程中运行您的“ProcessCode”方法。但是是的,对 Web 浏览器控件的调用应该只在 UI 线程上。
-
您是在启动时空白文档还是在启动时加载一些标记?你的问题不是很清楚。如果您想在启动时将其设为空白,您是否尝试过将 url 设置为“about:blank”?
-
事实证明,速度慢是由我省略的一些代码造成的。谁会想到
Directory.GetFiles(someNetworkPath)会很慢? :)
标签: c# .net webbrowser-control