0

我正在使用 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;
        }

我究竟做错了什么?你能帮我追踪泄漏或告诉我我的问题在哪里吗?在将位图用作图像源之前,我试图冻结它们,但应用程序仍在泄漏。

我将非常感谢您的所有建议。

谢谢

谢谢达里奥

4

1 回答 1

0
 // Release the Evf Image ref
 if (evfImage != null)
 {
     err = EDSDK.EdsRelease(stream); // this should release the evfImage
     evfImage = IntPtr.Zero;
 }

可能只是一个错字,但您两次释放流并且从未释放 evfImage。

于 2019-09-05T11:21:43.923 回答