侧边栏壁纸
博主头像
分享你我博主等级

行动起来,活在当下

  • 累计撰写 107 篇文章
  • 累计创建 13 个标签
  • 累计收到 0 条评论

目 录CONTENT

文章目录

.net core 3.1多线程使用PuppeteerSharp截图打开窗体过多导致卡死问题解决

管理员
2020-12-28 / 0 评论 / 0 点赞 / 2 阅读 / 37813 字
   /// <summary>
    /// 单个截图
    /// </summary>
    public class PuppeteerSharpHelp
    {
        public PuppeteerSharpHelp()
        {
        }
        //初始化线程数(非负数且小于或等于maxCount)
        public static int InitialCount { get; set; } = 1;
        //允许最大的线程数
        public static int MaxCount { get; set; } = 1;
        /// <summary>
        /// 截图完成回调
        /// </summary>
        public static event EventHandler ScreenshotComplete;
        /// <summary>
        /// 截图出错回调
        /// </summary>
        public static event EventHandler ScreenshotError;
        //异步线程锁
        private static SemaphoreSlim slimLock = new SemaphoreSlim(InitialCount, MaxCount);
        private static PuppeteerSharp.Browser browser = null;
        private static PuppeteerSharp.Page page = null;
        public static async Task Screenshot(string loadUrl, string savePath)
        {
            try
            {
                await slimLock.WaitAsync();
                //初始化浏览器
                await new BrowserFetcher().DownloadAsync(BrowserFetcher.DefaultRevision);
                if (browser == null)
                {
                    browser = await Puppeteer.LaunchAsync(new LaunchOptions
                    {
                        Headless = true,
                        DefaultViewport = new ViewPortOptions { Width = 1440, Height = 2560 },
                    });
                }
                if (page == null)
                {
                    var getPage = await browser.PagesAsync();
                    if (getPage.Length > 0)
                    {
                        page = getPage[0];
                    }
                    else
                    {
                        page = await browser.NewPageAsync();
                    }
                }
                page.Load += async (sender, e) =>
                {
                    try
                    {
                        var load = (Page)sender;
                        await page.ScreenshotAsync(savePath, new ScreenshotOptions() { Type = ScreenshotType.Png });
                        ScreenshotComplete(savePath, new ScreenshotEventArgs() { IsScreenshot = true, SavePath = savePath });
                        await browser.DisposeAsync();
                        browser = null;
                    }
                    catch (Exception ex)
                    {
                        ScreenshotError(savePath, new ScreenshotErrorEventArgs() { Error = ex, IsScreenshot = false, SavePath = savePath });
                    }
                };
                await page.SetViewportAsync(new ViewPortOptions
                {
                    Width = 1440,
                    Height = 2560
                });
                await page.GoToAsync(loadUrl);
                page.Close += async (sender, e) =>
                {
                    var pg = (Page)sender;
                    var size = await pg.Browser.PagesAsync();
                    if (size.Length <= 1)
                    {
                        //_browser?.CloseAsync();
                        await browser.DisposeAsync();
                        browser = null;
                        page = null;
                    }
                };
            }
            catch (Exception ex)
            {
                browser.Dispose();
                browser = null;
                throw ex;
            }
            finally
            {
                browser = null;
                page = null;
                GC.Collect();
                slimLock.Release();
            }
        }
        public static async void Screenshot(string loadUrl, string savePath, int width, int height)
        {
            try
            {
                await slimLock.WaitAsync();
                //初始化浏览器
                await new BrowserFetcher().DownloadAsync(BrowserFetcher.DefaultRevision);
                if (browser == null)
                {
                    browser = await Puppeteer.LaunchAsync(new LaunchOptions
                    {
                        Headless = true,
                        DefaultViewport = new ViewPortOptions { Width = width, Height = height },
                    });
                }
                if (page == null)
                {
                    var getPage = await browser.PagesAsync();
                    if (getPage.Length > 0)
                    {
                        page = getPage[0];
                    }
                    else
                    {
                        page = await browser.NewPageAsync();
                    }
                }
                page.Load += async (sender, e) =>
                {
                    try
                    {
                        var load = (Page)sender;
                        await page.ScreenshotAsync(savePath, new ScreenshotOptions() { Type = ScreenshotType.Png });
                        ScreenshotComplete(savePath, new ScreenshotEventArgs() { IsScreenshot = true, SavePath = savePath });
                        await browser.DisposeAsync();
                        browser = null;
                    }
                    catch (Exception ex)
                    {
                        ScreenshotError(savePath, new ScreenshotErrorEventArgs() { Error = ex, IsScreenshot = false, SavePath = savePath });
                    }
                };
                await page.SetViewportAsync(new ViewPortOptions
                {
                    Width = width,
                    Height = height
                });
                await page.GoToAsync(loadUrl, WaitUntilNavigation.Load);
            }
            catch (Exception ex)
            {
                browser.Dispose();
                browser = null;
                throw ex;
            }
            finally
            {
                slimLock.Release();
            }
        }
        public static async void Screenshot(string loadUrl, string savePath, ScreenshotType type)
        {
            try
            {
                await slimLock.WaitAsync();
                //初始化浏览器
                await new BrowserFetcher().DownloadAsync(BrowserFetcher.DefaultRevision);
                if (browser == null)
                {
                    browser = await Puppeteer.LaunchAsync(new LaunchOptions
                    {
                        Headless = true,
                        DefaultViewport = new ViewPortOptions { Width = 1440, Height = 2560 },
                    });
                }
                if (page == null)
                {
                    var getPage = await browser.PagesAsync();
                    if (getPage.Length > 0)
                    {
                        page = getPage[0];
                    }
                    else
                    {
                        page = await browser.NewPageAsync();
                    }
                }
                page.Load += async (sender, e) =>
                {
                    try
                    {
                        var load = (Page)sender;
                        await page.ScreenshotAsync(savePath, new ScreenshotOptions() { Type = type });
                        ScreenshotComplete(savePath, new ScreenshotEventArgs() { IsScreenshot = true, SavePath = savePath });
                        await browser.DisposeAsync();
                        browser = null;
                    }
                    catch (Exception ex)
                    {
                        ScreenshotError(savePath, new ScreenshotErrorEventArgs() { Error = ex, IsScreenshot = false, SavePath = savePath });
                    }
                };
                await page.SetViewportAsync(new ViewPortOptions
                {
                    Width = 1440,
                    Height = 2560
                });
                await page.GoToAsync(loadUrl, WaitUntilNavigation.Load);
            }
            catch (Exception ex)
            {
                browser.Dispose();
                browser = null;
                throw ex;
            }
            finally
            {
                slimLock.Release();
            }
        }
    }
    
   public class ScreenshotEventArgs : EventArgs
    {
        /// <summary>
        /// 截图成功为true
        /// </summary>
        public bool IsScreenshot { get; set; }
        /// <summary>
        /// 截图保存的路径
        /// </summary>
        public string SavePath { get; set; }
    }
    public class ScreenshotErrorEventArgs : EventArgs
    {
        /// <summary>
        /// 截图成功为true
        /// </summary>
        public bool IsScreenshot { get; set; }
        /// <summary>
        /// 截图保存的路径
        /// </summary>
        public string SavePath { get; set; }
        /// <summary>
        /// 出错内容
        /// </summary>
        public object Error { get; set; }
    }


测试:

        public void GetTest()
        {
            try
            {
                PuppeteerSharpHelp.InitialCount = 2;
                PuppeteerSharpHelp.MaxCount = 2;
                for (int i = 1; i <= 10; i++)
                {
                    Console.WriteLine("进来了-----------------------次数:" + i);
                    if ((i % 2) == 0)
                    {
                        PuppeteerSharpHelp.Screenshot("https://www.baidu.com", $"F://test{i}.png");
                    }
                    else
                    {
                        PuppeteerSharpHelp.Screenshot("https://www.csdn.net/", $"F://test{i}.png");
                    }
                }
                return new ApiResult(ResultCode.SUCCESS, "来了");
            }
            catch (Exception ex)
            {
                _logger.LogError(ex.ToString());
                return null;
            }
        }
 public void GetTest()
        {
            try
            {
                PuppeteerSharpHelp.InitialCount = 2;
                PuppeteerSharpHelp.MaxCount = 2;
                for (int i = 1; i <= 10; i++)
                {
                    Console.WriteLine("进来了-----------------------次数:" + i);
                    if ((i % 2) == 0)
                    {
                        Task.Run(() =>
                        {
                            PuppeteerSharpHelp.Screenshot("https://www.baidu.com", $"F://test{i}.png");
                        });
                    }
                    else
                    {
                        Task.Run(() =>
                        {
                            PuppeteerSharpHelp.Screenshot("https://www.csdn.net/", $"F://test{i}.png");
                        });
                    }
                }
                return new ApiResult(ResultCode.SUCCESS, "来了");
            }
            catch (Exception ex)
            {
                _logger.LogError(ex.ToString());
                return null;
            }
        }

结果:只打一个窗体完成十个循环或多线程截图

image.png

0

评论区