CopyRaster GP tool keeps open cursors (ArcObjects 9.3.1 SP2)

2263
4
08-02-2011 02:57 AM
StefanOffermann
Occasional Contributor II
Hi,

i have a problem with the CopyRaster geoprocessing tool. When I use the GP-Tool to execute it with the Geoprocessor object, it keeps 2 open cursors on my Oracle SDE. I have to copy many rasters from a local folder to the geodatabase. After some time I get ORA-0100: Maximum open cursors exceeded because the open cursors do not get closed until I close ArcMap (i am developing an ArcMap extension with C#). I have tried some things to free the c#-objects, but this does not close the open cursors. What can I do?

Here is the code which I use to copy the rasters from the file system to the Oracle SDE:

            var files = new Dictionary<string, string>();
            /* read directory structure and collect all BMP files */
            foreach (var file in files)
            {
                var fullRasterSourcePath = file.Key;
                var fullRasterSDE = @"Database Connections\vsdev0920.sde\MARA." + file.Value;

                var cpRas = new ESRI.ArcGIS.DataManagementTools.CopyRaster
                {
                    in_raster = fullRasterSourcePath,
                    out_rasterdataset = fullRasterSDE,
                    nodata_value = 0
                };
                var gp = new ESRI.ArcGIS.Geoprocessor.Geoprocessor();
                gp.Execute(cpRas, null);
                ESRI.ArcGIS.ADF.ComReleaser.ReleaseCOMObject(gp);
                ESRI.ArcGIS.ADF.ComReleaser.ReleaseCOMObject(cpRas);
                mygp = null;
                cpRas = null;

                GC.Collect();
                GC.WaitForPendingFinalizers();
                GC.Collect();
                GC.WaitForPendingFinalizers();
            }


After every execution of the CopyRaster tool, there are 2 more open cursors which I checked with the following SQL statement:

select sum(a.value) total_cur, avg(a.value) avg_cur, max(a.value) max_cur, 
s.username, s.machine
from v$sesstat a, v$statname b, v$session s 
where a.statistic# = b.statistic#  and s.sid=a.sid
and b.name = 'opened cursors current' 
group by s.username, s.machine
order by 1 desc;


Both client and SDE are at ArcGIS level 9.3.1 SP2

Best regards, Stefan
0 Kudos
4 Replies
DubravkoAntonic
New Contributor III
It seems to me problem is in ESRI-s objects that holds the lock not in your objects that you desperately trying to release.
Try this concept to reuse references and give GC some time by suspending the thread for Geoprocessor thread to release their inner objects. Had same kind of issues with other COM objects and sometime it helps.
If it doesnt help don't use anonymus types (var) then use explicit type IGeoProcessor.

var cpRas;// forcing reference reusing
var gp;
foreach (var file in files)
{

[INDENT]ESRI.ArcGIS.ADF.ComReleaser.ReleaseCOMObject(gp);
ESRI.ArcGIS.ADF.ComReleaser.ReleaseCOMObject(cpRas);

//pseudo part
if(sameAsBefore){
Thread.Sleep(1); or Threas.SpinWait(1);
// if doesn't makes a difference then
// use GC.Collect();
//         and       GC.WaitForPendingFinalizers();
}
[/INDENT]
}

System.Runtime.InteropServices.Marshal.FinalReleaseComObject(cpRas);
System.Runtime.InteropServices.Marshal.FinalReleaseComObject(gp);

regards Dubravko Antoni�?
0 Kudos
StefanOffermann
Occasional Contributor II
Thanks for your posting, but the cursors stay open 😞 I have moved the declarations of "cpRas" and "gp" just before the foreach-loop. So the references are reused in my code, but the open cursor count still raises and raises in each iteration...

i also tried to replace the "var" type by "IGPProcess" and "Geoprocessor", even "IGeoProcessor" from ESRI.ArcGIS.Geoprocessing library, but nothing changed.

Damn how can I force ArcObjects to release the database cursors? 😞

            ESRI.ArcGIS.Geoprocessor.IGPProcess cpRas;
            ESRI.ArcGIS.Geoprocessing.IGeoProcessor gp;

            foreach (var file in files)
            {
                var fullRasterSourcePath = file.Key;
                var fullRasterSDE = @"Database Connections\vsdev0920.sde\MARA." + file.Value;

                ESRI.ArcGIS.esriSystem.IVariantArray para = new ESRI.ArcGIS.esriSystem.VarArrayClass();
                para.Add(fullRasterSourcePath);
                para.Add(fullRasterSDE);
                gp = new ESRI.ArcGIS.Geoprocessing.GeoProcessorClass();
                gp.Execute("CopyRaster_management", para, null);

                ESRI.ArcGIS.ADF.ComReleaser.ReleaseCOMObject(gp);
                gp = null;

                System.Threading.Thread.Sleep(200);
                GC.Collect();
                GC.WaitForPendingFinalizers();
                System.Threading.Thread.Sleep(200);
                GC.Collect();
                GC.WaitForPendingFinalizers();
            }
0 Kudos
DubravkoAntonic
New Contributor III
Just passed through help and as I can see your usage of GP - Geoprocessor tool is as in sdk help, but with the difference that you call processor in for each loop. Therefore I suspect there could be a problem. I expect that release of cursors should be ok if you execute tool only once in one function call.


Try using result message to see if there are something that we can not see.
IGeoProcessorResult results = (IGeoProcessorResult)gp.Execute("CopyRaster", para, null);
if (results.Status != esriJobStatus.esriJobSucceeded)
{
[INDENT]log the message or show messagebox[/INDENT]
}

Object that is connecting to the base is gp not para so you should try to focus on this one.

If only one GP execution pass ok I'll try to make some king of loop from which I'll call function that makes GeoProcessing and after that wait with Application.DoEvents() for some time to let GP finish his work and release it self.

You have to consider that GP is COM object and that it will not be released as soon you start another loop in your foreach becuse GC is not releasing imedietly after you call Collect. It usually does Release after some time or memory usage.
So try :
a) putting FinalRelease inside foreach and experiment with DoEvents
b) use new GP only once before foreach and call Execute with different parameters inside foreach. This time we are using only one GP tool during whole foreach execution.

b) case is my favorite one
            var gp = new ESRI.ArcGIS.Geoprocessor.Geoprocessor();
            foreach (var file in files)
            {[INDENT]
                var fullRasterSourcePath = file.Key;
                var fullRasterSDE = @"Database Connections\vsdev0920.sde\MARA." + file.Value;

                var cpRas = new ESRI.ArcGIS.DataManagementTools.CopyRaster
                {[INDENT]
                    in_raster = fullRasterSourcePath,
                    out_rasterdataset = fullRasterSDE,
                    nodata_value = 0[/INDENT]
                };
               
                gp.Execute(cpRas, null);

                ESRI.ArcGIS.ADF.ComReleaser.ReleaseCOMObject(cpRas);

               // if no effect try inserting but this is not good practices
               //only if we are sure why we are doing this
               //Application.DoEvents(); Thread.Sleep(1);  Application.DoEvents();
                cpRas = null;[/INDENT]
            }
            ESRI.ArcGIS.ADF.ComReleaser.ReleaseCOMObject(gp);
            // or System.Runtime.InteropServices.Marshal.FinalReleaseComObject(gp);

Hope this will help, because I'm now with no idea, and I'm optimistic about b) case.
Regards Dubravko
0 Kudos
StefanOffermann
Occasional Contributor II
Thanks for your help! The problem was not directly related to the code mentioned so far. The reason why the cursors were kept open was a reference to the SDE workspace, which has been created some lines above the loop to copy the rasters. When I released the COM object referencing the workspace, all open cursors are closed 🙂 So it was a bad idea to open the workspace once and process all steps afterwards.

So I solved my problem by opening the workspace inside the loop and release the reference right at the end of the loop. Secondly, I refactored my code so that references to the workspace are opened and closed many times, to avoid a long-time opened workspace, which keeps open cursors.

Best regards, Stefan
0 Kudos