我使用 3rd 方库,它是原生 dll 的包装器。该库包含一个类型XImage
、XImage
一些属性和一个IntPtr Data()
方法。XImage
也实现IDisposable
了,但我不知道它是否正确实现。
我从 TCP 连接中获得了许多XImage
s 并将它们显示为PictureBox
.
我曾经将 'XImage' 转换为System.Drawing.Image
并在 a 中查看它们,PictureBox
但我得到了AccessViolationException
.
所以我做了一个包装,XImage
叫做Frame
.
public class Frame : IDisposable
{
public uint size { get; private set; }
private Image image;
public XImage XImage { get; set; }
public Image Image { get { return image ?? (image = GetBitmap(this.XImage)); } }
public DateTime Time { get; set; }
public Frame(XImage xImage)
{
this.XImage = xImage;
this.size = XImage.ImageBufferSize();
GC.AddMemoryPressure(size);
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
~Frame()
{
Dispose(false);
}
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
try
{
image.Dispose();
}
catch { }
finally
{
image = null;
}
try
{
MImage.Dispose();
}
catch { }
finally { XImage = null; }
}
GC.RemoveMemoryPressure(size);
}
}
并通过处理对Frame
我的引用解决了AccessViolationException
. 现在我有另一个问题,当我从 Visual Studio 运行程序时(F5 - 开始调试)一切都很好,但是当我从.exe
文件或(ctrl + F5 - 开始而不调试)运行它时,内存使用量越来越大直到我得到OutOfMemoryException
.(Biuld Configuration: Release - X86)。我应该怎么办 ?
- - 编辑 - -
我发现GC.AddMemoryPressure
或者GC.RemoveMemoryPressure
只是让垃圾收集更频繁地运行,我现在的问题是我有一些小对象,这些小对象有一个大型非托管内存的句柄,而 GC 没有收集这些小对象。
---- EDIT ----
调用GC.Collect
会在运行时解决问题,我设置了一个定时器并GC.Collect
定期调用,但它会使应用程序冻结一小段时间,所以我不想使用这种方法。