我在控制台应用程序中使用System.Windows.Forms.WebBrowser来呈现网页,然后在其上调用脚本。为了呈现网页,我使用Application.DoEvents来加载和执行脚本。
但有时应用程序会在调用Application.DoEvents时挂起。我没有找到理由。我不认为我在事件循环中创建了死锁。
Web上的许多人都说不应该使用Application.DoEvents,因为它会产生比解决的问题更多的问题。所以我认为必须有替代品。但我搜索了很多,找不到Application.DoEvents的替代方案。
有谁知道吗? 任何信息表示赞赏。提前谢谢!
感谢Noseratio的帮助,我完成了我的代码的起草,但仍然存在冻结问题。
以下代码为例(代码太长,所以我将其粘贴在pastebin上):http://pastebin.com/DkDcrirU
运行此代码时,偶尔会有至少一个窗口无法关闭。如果您附加到冻结过程,您会发现代码卡在以下行(由“>>>”表示):
public static bool NavigateLoadAndRender(WebBrowserContext browserContext, string url, TimeSpan loadTimeout, TimeSpan renderTime, out string errMsg)
{
ForceInitActiveXInstance(browserContext);
object axi = null;
Func<Uri> getBrowserUri = null;
Action<Uri> navigateBrowser = null;
Func<IHTMLDocument2> getBrowserDoc = null;
switch (browserContext.WebBrowserType)
{
case WebBrowserTypeEnum.Forms:
{
var browser = browserContext.GetWebBrowserAsFormsType();
getBrowserUri = () => browser.Url;
navigateBrowser = u =>
{
var finished = false;
browserContext.SyncContext.Post(state =>
{
browser.Navigate(u);
finished = true;
}, null);
while (!finished) Thread.Sleep(DefaultConfig_SyncContextPostCheckInterval);
};
getBrowserDoc = () =>
{
IHTMLDocument2 doc = null;
bool finished = false;
browserContext.SyncContext.Post(state =>
{
doc = (IHTMLDocument2)browser.Document.DomDocument;
finished = true;
}, null);
>>> while (!finished) Thread.Sleep(DefaultConfig_SyncContextPostCheckInterval);
return doc;
};
axi = GetActiveXInstance(browserContext);
}
break;
case WebBrowserTypeEnum.Wpf:
{
var browser = browserContext.GetWebBrowserAsWpfType();
axi = GetActiveXInstance(browser);
getBrowserUri = () => browser.Source;
navigateBrowser = u =>
{
var finished = false;
browserContext.SyncContext.Post(state =>
{
browser.Navigate(u);
finished = true;
}, null);
while (!finished) Thread.Sleep(DefaultConfig_SyncContextPostCheckInterval);
};
getBrowserDoc = () =>
{
IHTMLDocument2 doc = null;
bool finished = false;
browserContext.SyncContext.Post(state =>
{
doc = (IHTMLDocument2)browser.Document;
finished = true;
}, null);
while (!finished) Thread.Sleep(DefaultConfig_SyncContextPostCheckInterval);
return doc;
};
axi = GetActiveXInstance(browserContext);
}
break;
default: throw new ArgumentException("unknown browser type", browserContext.WebBrowserType.ToString());
}
var success = NavigateLoadAndRender(
axi, url,
getBrowserUri,
navigateBrowser,
//() => DoEvents(browser),
getBrowserDoc,
loadTimeout, renderTime, out errMsg);
return success;
}
任何人都知道发生了什么事?