c# - 程序正常运行 24 分钟,然后 GDI+ 中出现一般错误
问题描述
我制作了一个程序来一遍又一遍地截取特定窗口的屏幕截图,并且在执行压力测试时一切正常,直到第 4997 次迭代。
我猜屏幕截图部分的某处有泄漏,但我已尽一切努力防止它发生但无济于事。
这是 Screenshot.cs
[DllImport("user32.dll")]
private static extern IntPtr GetWindowRect(IntPtr hWnd, ref Rectangle rect);
[DllImport("gdi32.dll")]
private static extern IntPtr CreateCompatibleDC(IntPtr hdc);
[DllImport("gdi32.dll")]
private static extern IntPtr CreateCompatibleBitmap(IntPtr hdc,int nWidth,int nHeight);
[DllImport("gdi32.dll")]
private static extern IntPtr SelectObject(IntPtr hdc,IntPtr hgdiobj);
[DllImport("gdi32.dll")]
private static extern int DeleteDC(IntPtr hdc);
[DllImport("user32.dll")]
private static extern bool PrintWindow(IntPtr hwnd,IntPtr hdcBlt,UInt32 nFlags);
[DllImport("user32.dll")]
private static extern IntPtr GetWindowDC(IntPtr hwnd);
public static Bitmap MakeScreenshotOfWindow(IntPtr hWnd)
{
IntPtr hscrdc = GetWindowDC(hWnd);
Rectangle windowRect = new Rectangle();
GetWindowRect(hWnd, ref windowRect);
int width = Math.Abs(windowRect.X - windowRect.Width);
int height = Math.Abs(windowRect.Y - windowRect.Height);
IntPtr hbitmap = CreateCompatibleBitmap(hscrdc, width, height);
IntPtr hmemdc = CreateCompatibleDC(hscrdc);
SelectObject(hmemdc, hbitmap);
PrintWindow(hWnd, hmemdc, 0);
Bitmap bmp = Image.FromHbitmap(hbitmap);
DeleteDC(hscrdc);
DeleteDC(hmemdc);
return bmp;
}
这是我调用 MakeScreenshotOfWindow 函数的片段:
using (Bitmap screenShot = Screenshot.MakeScreenshotOfWindow(WindowHandle))
{
if (screenShot == null)
{
thumbnailError = "screenShot was null";
return false;
}
else
{
screenShot.Save($"{Program.thumbnailStorage}\\{assetId}-{assetType}-{t}.png", ImageFormat.Png);
screenShot.Dispose();
}
}
这是发生的完整异常
System.Runtime.InteropServices.ExternalException (0x80004005): A generic error occurred in GDI+.
at System.Drawing.Image.FromHbitmap(IntPtr hbitmap, IntPtr hpalette)
at System.Drawing.Image.FromHbitmap(IntPtr hbitmap)
at ThumbnailServer.Screenshot.PrintWindow(IntPtr hWnd) in C:\Users\darkg\source\repos\ThumbnailServer\ThumbnailServer\Screenshot.cs:line 69
at ThumbnailServer.ThumbnailGenerator.Click(Int32 t, Int32 assetId, Int32 assetType, String& thumbnailError, Int32 w, Int32 h, Boolean hideSky) in C:\Users\darkg\source\repos\ThumbnailServer\ThumbnailServer\ThumbnailGenerator.cs:line 72
解决方案
我通过添加以下内容来修复它:
[DllImport("gdi32.dll")]
private static extern IntPtr DeleteObject(IntPtr hwnd);
然后这个:
DeleteObject(hbitmap);
推荐阅读
- python - 是否有任何包可以模拟/伪造一个小数据集以便在 R/Python 中获得更多的行数?
- java - 有没有办法在不复制或不使用 Arraylist 的情况下扩展数组并动态增加数组大小?
- javascript - 如何在不使用新 API 的情况下获取 Instagram 照片
- excel - 使用 VBA Excel 生成 QR
- lambda - Soot - 无法为具有 lambda 表达式的 java 方法获取 soot cfg
- java - 向 InputDialog 添加注释
- kubernetes - 由于部署清单问题,无法进行掌舵安装
- c# - 使用 Google Drive API 请求访问特定预先存在文件的 OAuth2 范围
- authentication - Glassfish 5.1 上的身份验证表单出现空指针异常
- swift - SwiftUI:通过外部调用的函数更改@State 变量?