Я разрабатываю приложение, которое подключается к камере GigEVision и извлекает из нее изображения. В настоящее время я использую Pleora eBus SDK с C#.NET.
Приведенный ниже код является всего лишь тестовым приложением для подключения камеры — оно может передавать изображения, но быстро исчерпает память, если я не вызову GC.Collect(); Стоит отметить, что передаваемые изображения имеют большой размер (4096x3072), поэтому сбой происходит довольно быстро.
Сначала я подозревал, что проблема не в вызове Dispose(). Однако я могу вызвать Dispose() для каждого изображения прямо перед тем, как избавиться от ссылки на него, и это не решило проблему.
Я также пытался явно освобождать буферы, поступающие в обратный вызов потока отображения, но это не имело никакого эффекта.
Могу ли я вернуть свою память более элегантным способом?
using System;
using System.Windows.Forms;
using PvDotNet;
using PvGUIDotNet;
using System.Drawing;
namespace eBus_Connection
{
public partial class MainForm : Form
{
PvDeviceGEV camera;
PvStreamGEV stream;
PvPipeline pipeline;
PvDisplayThread thread;
bool updating = false;
public MainForm()
{
InitializeComponent();
}
private void MainForm_Shown(object sender, EventArgs e)
{
PvDeviceInfo info;
PvDeviceFinderForm form = new PvDeviceFinderForm();
form.ShowDialog();
info = form.Selected;
camera = PvDeviceGEV.CreateAndConnect(info) as PvDeviceGEV;
stream = PvStreamGEV.CreateAndOpen(info.ConnectionID) as PvStreamGEV;
pipeline = new PvPipeline(stream);
if (camera == null || stream == null)
throw new Exception("Camera or stream could not be created.");
camera.NegotiatePacketSize();
camera.SetStreamDestination(stream.LocalIPAddress, stream.LocalPort);
camera.StreamEnable();
camera.Parameters.ExecuteCommand("AcquisitionStart");
pipeline.Start();
thread = new PvDisplayThread();
thread.OnBufferDisplay += thread_OnBufferDisplay;
thread.Start(pipeline, camera.Parameters);
status.DisplayThread = thread;
status.Stream = stream;
}
void thread_OnBufferDisplay(PvDisplayThread aDisplayThread, PvBuffer aBuffer)
{
Bitmap b = new Bitmap((int)aBuffer.Image.Width, (int)aBuffer.Image.Height);
aBuffer.Image.CopyToBitmap(b);
BeginInvoke(new Action<Bitmap>(ChangeImage), b);
}
void ChangeImage(Bitmap b)
{
if (PictureBox.Image != null)
PictureBox.Dispose();
PictureBox.Image = b;
GC.Collect();//taking this away causes memory to leak rapidly.
}
}
}
PictureBox.Image.Dispose()
, а неPictureBox.Dispose()
. - person Michael Liu   schedule 01.07.2014