I get this message for line 84 and line 85 (the two, stacked using lines):
CA2000 : Microsoft.Reliability : In method 'RavenDataAccess.GetRavenDatabase()', object '<>g_initLocal9' is not disposed along all exception paths. Call System.IDisposable.Dispose on object '<>g_initLocal9' before all references to it are out of scope.
DocumentStore implements IDisposable.
Why? How else can I dispose the DocumentStore objects? They're created in a using block, and I dispose of them in my catch block. How should this be fixed?
private static IDocumentStore GetRavenDatabase()
{
Shards shards = new Shards();
try
{
using (DocumentStore docStore1 = new DocumentStore { Url = ConfigurationManager.AppSettings["RavenShard1"] }) // Line 84
using (DocumentStore docStore2 = new DocumentStore { Url = ConfigurationManager.AppSettings["RavenShard2"] }) // Line 85
{
shards.Add(docStore1);
shards.Add(docStore2);
}
using (ShardedDocumentStore documentStore = new ShardedDocumentStore(new ShardStrategy(), shards))
{
documentStore.Initialize();
IndexCreation.CreateIndexes(typeof(RavenDataAccess).Assembly, documentStore);
return documentStore;
}
}
catch
{
shards.ForEach(docStore => docStore.Dispose());
throw;
}
}
You have to ensure that you dispose all your newly created Disposable objects along any possible exception path. See below:
private static IDocumentStore GetRavenDatabase()
{
Shards shards = new Shards();
DocumentStore docStore1 = null;
DocumentStore docStore2 = null;
ShardedDocumentStore shardedDocumentStore = null;
ShardedDocumentStore tempShardedDocumentStore = null;
try
{
docStore1 = new DocumentStore();
docStore1.Url = ConfigurationManager.AppSettings["RavenShard1"];
docStore2 = new DocumentStore();
docStore2.Url = ConfigurationManager.AppSettings["RavenShard2"];
shards.Add(docStore1);
shards.Add(docStore2);
tempShardedDocumentStore = new ShardedDocumentStore(new ShardStrategy(), shards);
tempShardedDocumentStore.Initialize();
IndexCreation.CreateIndexes(typeof(RavenDataAccess).Assembly, tempShardedDocumentStore);
docStore1 = null;
docStore2 = null;
shardedDocumentStore = tempShardedDocumentStore;
tempShardedDocumentStore = null;
return shardedDocumentStore;
}
finally
{
if (tempShardedDocumentStore != null) { tempShardedDocumentStore.Dispose(); }
if (docStore1 != null) { docStore1.Dispose(); }
if (docStore2 != null) { docStore2.Dispose(); }
}
}
CA seems to have a problem with the inline property initializers but if you break them out this should work. Key thing is to ensure that no matter where an exception is thrown in the try block, all your new objects that can be disposed are cleaned up.
By setting the temp references you no longer need to null
(docStore1
, docStore2
, and tempShardedDocumentStore
) just prior to returning, you can check in the finally block to see if they in fact were set to null
, if not, an exception occurred somewhere and you can dispose of them before execution leaves this method.
Note docStore1
and docStore2
are temporary references as they are added to the Shards
collection.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With