我正在使用 Canon EDSDK 库开发小型 c# wpf 应用程序。我正在使用实时查看功能,在我的桌面应用程序中显示来自佳能相机的实时图片。
在实时取景过程中(while 循环),应用程序在内存中增长。我知道它应该增长,一段时间后 GC 运行并清除内存。但是即使在 GC 清除内存之后,它也永远不会回到开始级别。
此外,经过长时间的工作,我的应用程序关闭的时间非常长 - 有时甚至需要几分钟才能完全关闭它。
我期待,我有内存泄漏,但我看不到它在哪里。
这是我的主while循环的实时视图方法:
private uint DownloadEvfData(MainWindow MW)
{
uint err = EDSDK.EDS_ERR_OK;
IntPtr stream = new IntPtr();
IntPtr evfImage = new IntPtr();
BitmapImage bmp = new BitmapImage();
var transform = new ScaleTransform(-1, 1, 0, 0);
while (isLVRunning)
{
// Create an Eds Memory Stream
err = EDSDK.EdsCreateMemoryStream(0, out stream);
// Create an Eds EVF Image ref
if (err == EDSDK.EDS_ERR_OK)
{
err = EDSDK.EdsCreateEvfImageRef(stream, out evfImage);
}
// Download the EVF image
if (err == EDSDK.EDS_ERR_OK)
err = EDSDK.EdsDownloadEvfImage(cameraDev,
evfImage);
bmp = GetEvfImage(stream);
// do something with the bitmap
if (bmp != null)
{
// I need to show mirror flipped image
var mirror_bmp = new TransformedBitmap();
mirror_bmp.BeginInit();
mirror_bmp.Source = bmp;
mirror_bmp.Transform = transform;
mirror_bmp.EndInit();
mirror_bmp.Freeze();
MW.image1.Source = null;
MW.image1.Source = mirror_bmp;
RefreshScreen();
bmp = null;
mirror_bmp = null;
}
// Release the Evf Image ref
if (evfImage != null)
{
err = EDSDK.EdsRelease(stream);
evfImage = IntPtr.Zero;
}
// Release the stream
if (stream != null)
{
err = EDSDK.EdsRelease(stream);
stream = IntPtr.Zero;
}
}
transform = null;
return err;
}
为实时取景返回单个 BitmapImage(单帧)的方法如下所示:
public unsafe static BitmapImage GetEvfImage(IntPtr evfStream)
{
IntPtr jpgPointer;
uint err;
uint length = 0;
BitmapImage i = null;
err = EDSDK.EdsGetPointer(evfStream, out jpgPointer);
if (err == EDSDK.EDS_ERR_OK)
err = EDSDK.EdsGetLength(evfStream, out length);
if (err == EDSDK.EDS_ERR_OK)
{
if (length != 0)
{
using (UnmanagedMemoryStream ums = new UnmanagedMemoryStream
((byte*)jpgPointer.ToPointer(), length, length, FileAccess.Read))
{
i = new BitmapImage();
i.BeginInit();
i.CacheOption = BitmapCacheOption.OnLoad;
i.StreamSource = ums;
i.EndInit();
i.Freeze();
}
}
}
return i;
}
我究竟做错了什么?你能帮我追踪泄漏或告诉我我的问题在哪里吗?在将位图用作图像源之前,我试图冻结它们,但应用程序仍在泄漏。
我将非常感谢您的所有建议。
谢谢
谢谢达里奥