/// <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; } }
结果:只打一个窗体完成十个循环或多线程截图
评论区