I am writing to some tables in a database in C# using a 3rd party database library: Esri file-geodatabase-api. For each table type I have implemented a writer class. I pass a reference to a database object to each writer. Each writer then opens its own table in the database.
Both the database and the table class (3rd party) have Close() methods. They also implement IDisposable!? According to Esri samples I should call Close().
Here is a simplified version of my code. Am I doing things right here? Coming from C++ the automatic garbage collection confuses me.
public class TableWriter : IDisposable
{
// Geodatabase is a 3rd party class that implements IDisposable and has Close() method:
private Geodatabase geoDatabase_;
// Table is a 3rd party class that implements IDisposable and has Close() method:
protected Table table_;
private string tableName_;
private bool disposing_;
public TableWriter(Geodatabase geoDatabase, string tableName)
{
geoDatabase_ = geoDatabase;
tableName_ = tableName;
disposing_ = false;
}
// Constructors of subclasses calls this:
public void CreateTable(List<FieldDef> fieldDefList)
{
table_ = geoDatabase_.CreateTable(tableName_, fieldDefList.ToArray(), "");
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (disposed_)
{
return;
}
if(disposing) // called by user and not garbage collector
{
table_.Close();
table_.Dispose(); // can/should I do both Close and Dispose?
geoDatabase_ = null; // decrement reference count?
}
disposed_ = true;
}
// subclasses override this (they cast TableRow to a subtype):
public virtual void Write(TableRow tableRow){}
}
The export to database is triggered from a gui. I got a crash when I ran this export many times in sequence. I have since rewritten my code using the Dispose pattern and have not yet managed to trigger the crash. The crash seemed a bit random. Sometimes I could run it 5 times in row without a crash other times 15 times in row without a crash. The stack of the crash is this:
[19352] Exception Details: Cannot access a disposed object. Object name: 'Geodatabase'.
[19352] at Esri.FileGDB.Geodatabase.get_NativeGeodatabase()
[19352] at Esri.FileGDB.Table.Shutdown()
[19352] at Esri.FileGDB.Table.Dispose(Boolean A_0)
To me it seems that the garbage collector called automatic code that double deleted a table in one of the writers.