Below script is very standard for running any geoprocessing tool using ArcObjects but it hardly releases memory. It is helping the tool crashes after processing few 100 datasets. Please help in this regard. Thanks in advance.
geoprocessor.ClearMessages();
// Set the overwrite output option to true
geoprocessor.OverwriteOutput = true;
try
{
Logger.Write("RunTool is started", "AppLog");
// Execute the tool
geoprocessor.Execute(process, null);
ReturnMessages(geoprocessor);
ESRI.ArcGIS.ADF.ComReleaser.ReleaseCOMObject(geoprocessor);
ESRI.ArcGIS.ADF.ComReleaser.ReleaseCOMObject(process);
geoprocessor = null;
process = null;
}
catch (Exception ex)
{
Logger.Write("Exception in RunTool::"+ex.Message, "ExceptionHandling");
ReturnMessages(geoprocessor);
}
You seemed to have neglected to say what exactly it is you are running? What is process in geoprocessor.Execute(process, null)? What Tool is it and what where the supplied parameters?
Hi,
I missed it accidentally just due to considered it as abstraction as it happened for all types of operations in general such as 'Project', 'Merge' etc. Few others we moved to use plain arcobjects using c# related to geodatabase.
The other parameters would be shapefile paths depending on the parameters require for a given operation.
@umasurya sykam First of all - your code missing "finally" block. You need to realease all COM objects int it. So if exception occurs in some situations - it always release COM objects and it's memory. For example:
Geoprocessor geoprocessor = null;
Process process= null;
try
{
geoprocessor = new Geoprocessor();
process = new Process();
geoprocessor.Execute(process, null);
ReturnMessages(geoprocessor);
}
catch()
{
Logger.Write("Exception in RunTool::"+ex.Message, "ExceptionHandling");
ReturnMessages(geoprocessor);
}
finaly
{
if(geoprocessor != null)
{
ESRI.ArcGIS.ADF.ComReleaser.ReleaseCOMObject(geoprocessor);
geoprocessor =null;
}
if(process != null)
{
ESRI.ArcGIS.ADF.ComReleaser.ReleaseCOMObject(process );
process =null;
}
}
Hi,
Although I'm not releasing within finally block, they are being released within the try block itself properly and those 2 lines of code always get executed. But memory is not being recovered after that.
Another question I have is normally we are releasing eari COM objects using Marshal.ReleaseComObject.
Is the Geoprocessor class not a COM object?
You need to check if it is COM object, if not - check if it is IDisposable. I have smart function for that:
public static int Release(object comObj)
{
try
{
if (comObj != null)
{
if (Marshal.IsComObject(comObj))
{
try
{
return Marshal.ReleaseComObject(comObj);
}
catch
{
comObj = null;
}
}
else
{
var disposable = comObj as IDisposable;
if (disposable != null)
{
disposable.Dispose();
return 0;
}
}
}
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine("CATCH: " + ex.Message);
}
return -999;
}
How to use function:
finally
{
if (geoprocessor != null)
{
Release(geoprocessor);
geoprocessor= null;
}
}