首页 > 解决方案 > 多次打开多个网页后,经常出现卡顿

问题描述

我正在开发一个经常请求新网页的网络爬虫。在测试过程中,程序经常死机。

我编写了一个测试用例,解释了我的用法和发生问题的场景。

有时候打开一个网页10次,打开20次就卡住了。打开网页多少次,我不确定。

using CefSharp;
using CefSharp.WinForms;
using System;
using System.Windows.Forms;

namespace WindowsFormsApp2
{
    public partial class Form1 : Form
    {
        ChromiumWebBrowser browser;

        System.Timers.Timer timer;
        int i = 1;

        public Form1()
        {
            InitializeComponent();

            timer = new System.Timers.Timer(400) { AutoReset = true };//Timer, automatically open a new web page
            timer.Elapsed += Timer_Elapsed;

            browser = new ChromiumWebBrowser("www.baidu.com") { Parent = splitContainer1.Panel1, Dock = DockStyle.Fill };
            browser.LifeSpanHandler = new LifeSpanHandler(splitContainer1.Panel2);
            browser.FrameLoadEnd += Browser_FrameLoadEnd;
        }

        private void Browser_FrameLoadEnd(object sender, FrameLoadEndEventArgs e)
        {
            if (e.Frame.IsMain == false) return;
            timer.Start();
        }

        private void Timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            i = i > 1 ? 1 : i + 1;
            browser.ExecuteScriptAsync("document.getElementsByClassName('mnav c-font-normal c-color-t')[" + (i) + "].click()");//Open a link in the web page
        }
    }


    class LifeSpanHandler : ILifeSpanHandler
    {
        Control host;

        internal LifeSpanHandler(Control host)
        {
            this.host = host;
        }

        public bool DoClose(IWebBrowser chromiumWebBrowser, IBrowser browser)
        {
            return false;
        }

        public void OnAfterCreated(IWebBrowser chromiumWebBrowser, IBrowser browser)
        {

        }

        public void OnBeforeClose(IWebBrowser chromiumWebBrowser, IBrowser browser)
        {

        }

        public bool OnBeforePopup(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, string targetUrl, string targetFrameName, WindowOpenDisposition targetDisposition, bool userGesture, IPopupFeatures popupFeatures, IWindowInfo windowInfo, IBrowserSettings browserSettings, ref bool noJavascriptAccess, out IWebBrowser newBrowser)
        {
            newBrowser = null;

            var webBrowser = (ChromiumWebBrowser)chromiumWebBrowser;
            webBrowser.Invoke(new Action(() =>
            {
                if (host.HasChildren) host.Controls[0].Dispose();
                var control = new Control { Parent = host, Dock = DockStyle.Fill };
                control.CreateControl();
                windowInfo.SetAsChild(control.Handle);
            }));

            return false;
        }
    }
}

测试代码放在 GitHub 上,也就是 Visual Studio 2019 项目。我们希望您可以在本地执行项目,以便更直观地发现问题。非常感谢。

https://github.com/haohaodz/cefsharp-form-vs2019-problem.git

标签: cefsharp

解决方案


你用其他网站测试过吗?

对其他网站的高频率请求也可能导致死锁。

问题是否通过 github.com/cefsharp/CefSharp.MinimalExample 重现

该问题不会在 github.com/cefsharp/CefSharp.MinimalExample 中重现。

在 BrowserTabUserControl.cs

browser.LifeSpanHandler = new LifeSpanHandler(openPopupsAsTabs: false);

它默认在新窗口中打开一个网页。高频率打开多个网页,冻结问题不重现。

我将 openPopupsAsTabs 更改为 true 并在选项卡中打开一个新页面

browser.LifeSpanHandler = new LifeSpanHandler(openPopupsAsTabs: true);

高频率打开多个网页,程序会死机。程序在 dispose 方法中冻结:

System.Windows.Forms .dll! System.Windows.Forms . UnsafeNativeMethods.DestroyWindow ( 
     System.Runtime.InteropServices . handleref hWnd) unknown
System.Windows.Forms .dll! System.Windows.Forms . NativeWindow.DestroyHandle () unknown
System.Windows.Forms .dll! System.Windows.Forms . Control.DestroyHandle () unknown
System.Windows.Forms .dll! System.Windows.Forms . Control.Dispose (bool disposing) unknown
System.dll ! System.ComponentModel.Component . dispose() unknown

有时程序突然退出,出现异常:

Exception thrown:“ System.IO.PipeException ”(located at System.ServiceModel.dll (2)
Exception thrown:“ System.ServiceModel.CommunicationException ”(located at System.ServiceModel.dll (2)
Exception thrown:“ System.ServiceModel.CommunicationException ”(located at System.ServiceModel.dll (2)
Exception thrown:“ System.ServiceModel.CommunicationException ”(located at System.ServiceModel.dll (2)
Exception thrown:“ System.ServiceModel.CommunicationException ”(located at System.ServiceModel.Internals . DLL)
Exception thrown:“ System.ServiceModel.CommunicationException ”(located at System.ServiceModel.Internals . DLL)
Exception thrown:“ System.ServiceModel.CommunicationObjectFaultedException ”(located at System.ServiceModel.dll (2)

推荐阅读