在我的程序中,我每秒使用计时器捕获一个destop窗口的屏幕截图: 异常消息是:
System.OutOfMemoryException was unhandled
HResult=-2147024882
Message=Out of memory.
Source=System.Drawing
StackTrace:
at System.Drawing.Image.Save(String filename, ImageCodecInfo encoder, EncoderParameters encoderParams)
at System.Drawing.Image.Save(String filename, ImageFormat format)
at CapturedDesktop.Form1.screenshots(String filename) in d:\C-Sharp\CapturedDesktop\CapturedDesktop\CapturedDesktop\Form1.cs:line 53
at CapturedDesktop.Form1.CaptureScreenshot() in d:\C-Sharp\CapturedDesktop\CapturedDesktop\CapturedDesktop\Form1.cs:line 31
at CapturedDesktop.Form1.timer1_Tick(Object sender, EventArgs e) in d:\C-Sharp\CapturedDesktop\CapturedDesktop\CapturedDesktop\Form1.cs:line 63
at System.Windows.Forms.Timer.OnTick(EventArgs e)
at System.Windows.Forms.Timer.TimerNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData)
at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
at System.Windows.Forms.Application.Run(Form mainForm)
at CapturedDesktop.Program.Main() in d:\C-Sharp\CapturedDesktop\CapturedDesktop\CapturedDesktop\Program.cs:line 19
at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
InnerException:
例外是在线:
bmpScreenshot.Save(filename, ImageFormat.Gif);
对硬盘来说,图像直到文件编号000110是很好的,这意味着程序工作正常110秒后出现异常。
也许我应该在某处处理bmp变量?
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Drawing.Imaging;
using System.IO;
using unfreez_wrapper;
namespace CapturedDesktop
{
public partial class Form1 : Form
{
int screens;
string gifsdirectory;
UnFreezWrapper unfreez;
public Form1()
{
InitializeComponent();
unfreez = new UnFreezWrapper();
timer1.Enabled = false;
screens = 0;
gifsdirectory = @"C:\Temp\CapturedDesktop\";
}
private void CaptureScreenshot()
{
screens++;
screenshots(gifsdirectory + screens.ToString("D6") + ".gif");
}
public static void screenshots(string filename)
{
//Create a new bitmap.
var bmpScreenshot = new Bitmap(Screen.PrimaryScreen.Bounds.Width,
Screen.PrimaryScreen.Bounds.Height,
PixelFormat.Format32bppArgb);
// Create a graphics object from the bitmap.
var gfxScreenshot = Graphics.FromImage(bmpScreenshot);
// Take the screenshot from the upper left corner to the right bottom corner.
gfxScreenshot.CopyFromScreen(Screen.PrimaryScreen.Bounds.X,
Screen.PrimaryScreen.Bounds.Y,
0,
0,
Screen.PrimaryScreen.Bounds.Size,
CopyPixelOperation.SourceCopy);
// Save the screenshot to the specified path that the user has chosen.
bmpScreenshot.Save(filename, ImageFormat.Gif);
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void timer1_Tick(object sender, EventArgs e)
{
CaptureScreenshot();
}
private void AnimatedGifButton_Click(object sender, EventArgs e)
{
List<string> myGifList = new List<string>();
FileInfo[] fi;
DirectoryInfo dir1 = new DirectoryInfo(gifsdirectory);
fi = dir1.GetFiles("*.gif");
for (int i = 0; i < fi.Length; i++)
{
myGifList.Add(fi[i].FullName);
}
unfreez.MakeGIF(myGifList, gifsdirectory + "agif", 100, true);
}
}
}
答案 0 :(得分:3)
保存图片后,您需要Dispose
它。否则,您将所有责任推到GC。 GC有时可以保存您,有时不会。
鉴于图像大小等于屏幕大小,这意味着图像占用的内存也将是巨大的。你应该在你不需要的时候立即处理它。
public static void screenshots(string filename)
{
//Create a new bitmap.
using( var bmpScreenshot = new Bitmap(Screen.PrimaryScreen.Bounds.Width,
Screen.PrimaryScreen.Bounds.Height,
PixelFormat.Format32bppArgb))
{
// Create a graphics object from the bitmap.
using(var gfxScreenshot = Graphics.FromImage(bmpScreenshot))
{
// Take the screenshot from the upper left corner to the right bottom corner.
gfxScreenshot.CopyFromScreen(Screen.PrimaryScreen.Bounds.X,
Screen.PrimaryScreen.Bounds.Y,
0,
0,
Screen.PrimaryScreen.Bounds.Size,
CopyPixelOperation.SourceCopy);
}
// Save the screenshot to the specified path that the user has chosen.
bmpScreenshot.Save(filename, ImageFormat.Gif);
}
}
首选using statements到Dispose
一次性资源。