2

我在控制台应用程序中使用 System.Windows.Forms.WebBrowser 来呈现网页,然后在其上调用脚本。为了呈现网页,我使用 Application.DoEvents 来加载和执行脚本。

但是有时应用程序会在调用 Application.DoEvents 时挂起。我找不到任何理由。我不认为我在事件循环上造成死锁。

网络上的许多人说根本不应该使用 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;
}

有谁知道发生了什么?

4

0 回答 0