I'm working on application which will never shutdown... the main interface is containing a MapControl control, in order for the application to dynamicaly display on the map data received from other applications.We are developing with ArcGIS Engine 10.0 SP4, C#.net and Visual Studio 2010.We use GraphicTracker (4 to manage display order) to draw geometries (points and curve polylines).We currently face a Memory Leak for this application when doing stress tests : we send data to the application every second or 2 seconds, each time the application must clean the Graphic Tracker, release all COM Objects and draw again new data on the Graphic Tracker. after 2 or 3 hours, we reach an OutOfMemory Exception or -2147467259 runtime error... But our application is a 24/24 hours system and should never stop, neither restart !I guess, my release objects methods are wrong, but can't find a solution...So could somebody look to my code for any solutions or ideas ?Form1 = simple Form with MapControl + 2 buttons to start/stop a 1 second Timer which send clean/drawing order for 10000 public partial class Form1 : Form
{
...
private void Form1_Load(object sender, EventArgs e)
{
// Load on MXD map (sample : 1 shapefile of world countries)
this.LoadMyMXDMap();
// Initialize the Timer
this.InitializeMyTimer();
}
private void BtnStartMyTimer_Click(object sender, EventArgs e)
{
timer1.Start();
}
...
private void InitializeMyTimer()
{
timer1.Interval = 1000;
}
private void Timer1_Tick(object sender, EventArgs e)
{
// Stop the Timer before drawing
timer1.Stop();
// Use the Graphic Tracker Controler to perform a new drawing of 10000 points
if (this.graphicTrackerControler != null)
{
// Try a clean dispose & release of all COM objects
// MEMORY LEAK must come from this Method ??
this.graphicTrackerControler.DisposeGraphicTracker();
}
// Initialize new Graphic Tracker Controler and necessary objects
this.graphicTrackerControler = new GraphicsControler();
this.graphicTrackerControler.InitializeGraphicTracker();
// Draw on Graphic Trackers 10000 point's geometries
this.graphicTrackerControler.DrawPointsOnGraphicTracker();
// Restart the Timer after drawing
timer1.Start();
}
private void LoadMyMXDMap()
{
// my MXD doc map
string mxdFilePath = @"C:\my_maps\WORLD.mxd";
IMapDocument mapDocument = new MapDocumentClass();
mapDocument.Open(mxdFilePath);
// Display the map on Map Control
Form1.CurrentMap = mapDocument.get_Map(0);
this.axMapControl.Map = Form1.CurrentMap;
}
}
one Class "GraphicsControler" which manage the Graphic Tracker (initialize, dispose, draw) and added geometries
public class GraphicsControler
{
/// <summary> Graphic Tracker
/// </summary>
private IGraphicTracker graphicTrackerLayer;
/// <summary> List of Geometries added to the Graphic Tracker
/// </summary>
private List<IGeometry> listOfGeometries;
/// <summary> Symbol for Point's geometries on the Graphic Tracker
/// </summary>
private IGraphicTrackerSymbol symbolForPoints;
public void DrawPointsOnGraphicTracker()
{
try
{
if (this.graphicTrackerLayer != null)
{
// Disable graphic tracker auto-refresh
this.graphicTrackerLayer.SuspendUpdate = true;
IGeometry geometry;
IPoint point;
double coordX = 500;
double coordY = 5000;
// Add 10000 point geometries to the Graphic Tracker
for (int i = 0; i < 10000; i++)
{
coordX = coordX + 500;
coordY = coordY + 600;
point = new PointClass();
point.PutCoords(coordX, coordY);
geometry = point as IGeometry;
// Add the geometry to the graphic tracker
this.graphicTrackerLayer.Add(geometry, this.symbolForPoints);
// Preserve the added geometry for future COM release
this.listOfGeometries.Add(geometry);
}
// Enable graphic tracker auto-refresh
this.graphicTrackerLayer.SuspendUpdate = false;
}
}
catch (Exception exc)
{
MessageBox.Show(exc.Message, "DrawPointsOnGraphicTracker");
}
}
public void InitializeGraphicTracker()
{
try
{
this.graphicTrackerLayer = new GraphicTrackerClass();
this.graphicTrackerLayer.Initialize(Form1.CurrentMap as IBasicMap);
// Create one Symbol for the added points
this.CreateGraphicTrackerSymbolForPoints();
this.listOfGeometries = new List<IGeometry>();
}
catch (Exception exc)
{
MessageBox.Show(exc.Message, "InitializeGraphicTracker");
}
}
public void DisposeGraphicTracker()
{
try
{
// MEMORY LEAK must come from this Method ??
if (this.listOfGeometries != null)
{
if (this.listOfGeometries.Count > 0)
{
// Release COM for each Geometry added to the Graphic Tracker
foreach (IGeometry item in this.listOfGeometries)
{
item.SetEmpty();
this.CompleteReleaseOfCOMObject(item);
}
this.listOfGeometries.Clear();
}
}
if (this.graphicTrackerLayer != null)
{
// Disable graphic tracker auto-refresh
this.graphicTrackerLayer.SuspendUpdate = true;
// Delete all geometries added to the Graphic Tracker
// this method seams to clean the Graphic Tracker, without releasing memory
this.graphicTrackerLayer.RemoveAll();
// Enable graphic tracker auto-refresh
this.graphicTrackerLayer.SuspendUpdate = false;
}
// Release my Symbol
this.CompleteReleaseOfCOMObject(this.symbolForPoints);
// Release my Graphic Tracker
this.CompleteReleaseOfCOMObject(this.graphicTrackerLayer);
}
catch (Exception exc)
{
MessageBox.Show(exc.Message, "DisposeGraphicTracker");
}
}
private void CreateGraphicTrackerSymbolForPoints()
{
try
{
if (this.graphicTrackerLayer != null)
{
ICharacterMarkerSymbol characterMarkerSymbol;
stdole.IFontDisp symbolFont = new stdole.StdFontClass() as stdole.IFontDisp;
symbolFont.Name = "ESRI Default Marker";
characterMarkerSymbol = new CharacterMarkerSymbolClass();
characterMarkerSymbol.Font = symbolFont;
characterMarkerSymbol.Color = new RgbColorClass() { Red = 0, Green = 0, Blue = 0 };
characterMarkerSymbol.CharacterIndex = 86;
characterMarkerSymbol.Size = 10;
this.symbolForPoints = this.graphicTrackerLayer.CreateSymbol(characterMarkerSymbol as ISymbol, null);
}
}
catch (Exception exc)
{
MessageBox.Show(exc.Message, "CreateGraphicTrackerSymbolForPoints");
}
}
private void CompleteReleaseOfCOMObject(object objetALiberer)
{
try
{
ComReleaser.ReleaseCOMObject(objetALiberer);
if (objetALiberer != null)
{
int refsLeft = 0;
do
{
refsLeft = Marshal.ReleaseComObject(objetALiberer);
}
while (refsLeft > 0);
}
}
catch (Exception exc)
{
MessageBox.Show(exc.Message, "CompleteReleaseOfCOMObject");
}
}
}
Thanks in advance for any help !complete source code in .zip is attached.