在控制台应用程序中替代Application.DoEvents以使Forms.WebBrowser加载javascripts

时间:2015-05-09 03:47:19

标签: webbrowser-control doevents

我在控制台应用程序中使用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;
}

任何人都知道发生了什么事?

0 个答案:

没有答案