I'm working with ArcObjects to set up a batch import from xls and csv files into a geodatabase. That part works fine, but after the import, I want to delete the file. This, however, doesn't work, because the file is still open. None of the interfaces being used descend from IDisposable or expose a Close method. I've also tried using a ComReleaser to force close all of the COM objects that I open, but that doesn't work either. The only things I've seen pertaining to closing a connection say that I need to remove all references to these types and force garbage collection, which is against standards (for good reason).
Here's the method I'm using for the excel import:
private ServiceResult<IEnumerable<int>> InsertControlsFromXls(FileInfo xlsFile) {
ServiceResult<IEnumerable<int>> result = new ServiceResult<IEnumerable<int>>();
using(ComReleaser comReleaser = new ComReleaser()) {
//read in the spreadsheet as a workspace
Type factoryType = Type.GetTypeFromProgID("esriDataSourcesOleDB.ExcelWorkspaceFactory");
IWorkspaceFactory workspaceFactory = (IWorkspaceFactory)Activator.CreateInstance(factoryType);
IWorkspace workspace = workspaceFactory.OpenFromFile(xlsFile.FullName, 0);
IFeatureWorkspace remoteWorkspace = (IFeatureWorkspace)OpenWorkspace();
IFeatureWorkspace featureWorkspace = (IFeatureWorkspace)workspace;
IWorkspaceEdit2 session = (IWorkspaceEdit2)remoteWorkspace;
IMultiuserWorkspaceEdit multiuserWorkspace = (IMultiuserWorkspaceEdit)remoteWorkspace;
comReleaser.ManageLifetime(workspaceFactory);
comReleaser.ManageLifetime(workspace);
comReleaser.ManageLifetime(remoteWorkspace);
comReleaser.ManageLifetime(featureWorkspace);
comReleaser.ManageLifetime(session);
comReleaser.ManageLifetime(multiuserWorkspace);
try {
//session.StartEditing(false);
multiuserWorkspace.StartMultiuserEditing(esriMultiuserEditSessionMode.esriMESMVersioned);
session.StartEditOperation();
Match tableMatch = _tableRecReg.Match(xlsFile.Name);
string tableName = tableMatch.Success ? tableMatch.Groups[1].Value + "$" : "Sheet1$";
ITable table = featureWorkspace.OpenTable(tableName);
result.Value = CopyAllFeatures(table, remoteWorkspace.OpenFeatureClass(AppSettings.DefaultSchema + "." + ControlMap.TableName));
session.StopEditOperation();
session.StopEditing(true);
} catch {
session.AbortEditOperation();
session.StopEditing(false);
throw;
}
}
return result;
}
I asked this question on Stack Exchange too, but no responses so far: https://stackoverflow.com/questions/30783703/arcobjects-excelworkspacefactory-wont-release-excel-file
Edit: To clarify, this is using ArcObjects 10.3, for which the API is slightly different from 9.3.
-
possible duplicate of How do I remove Schema Locks from a File GeoDatabase in Java in ArcGis 9.3?Brad Nesom– Brad Nesom2015年06月12日 15:27:46 +00:00Commented Jun 12, 2015 at 15:27
-
I've always used ReleaseComObject when I'm done... msdn.microsoft.com/en-us/library/…, I would release any rows, cursors, table/featureclass and workspace that you've opened using this method.Michael Stimson– Michael Stimson2015年06月15日 02:54:55 +00:00Commented Jun 15, 2015 at 2:54
-
1@MichaelMiles-Stimson I tried that too after reading the link Brad listed, but that didn't work either. I guess I may have missed something, but I'm pretty sure I called it on everything. That being said, though, the ComReleaser class is supposed to be using ReleaseComObject under the hood. I'm not sure what the implementation is like, though, so who knows if it's recursive or what not.Ixonal– Ixonal2015年06月15日 13:22:17 +00:00Commented Jun 15, 2015 at 13:22
1 Answer 1
Ok, I got it to work by going hog-wild with ComReleaser objects. Basically, I scanned through my code, and anytime I found anything that was at all from ArcObjects, I attached a ComReleaser to manage it. Basically, I'm just doing manual memory management. At any rate, it does seem to release the file, so long as EVERYTHING is released (even if it doesn't seem relevant). As stated in comments above, the ComReleaser class should use ReleaseComObject under the hood, so that path should work as well.
-
It's much better to manually call ReleaseComObject when the object needs to be released, than to attach the ComReleaser to each object. ComReleaser greatly increases your chance of releasing a RCW needed elsewhere in your app.Rich Wawrzonek– Rich Wawrzonek2015年06月15日 19:36:38 +00:00Commented Jun 15, 2015 at 19:36