Reputation: 3331
I have a a list of disposable items that I am adding to collection that already contains a number of disposable items. I wrap the code in a try...finally block so that if an exception is thrown while I am copying the items from the list to the collection all the objects in the list get disposed of correctly:
private static void LoadMenuItems(ApplicationMenu parent)
{
List<ApplicationMenuItem> items = null;
try
{
items = DataContext.GetMenuItems(parent.Id);
foreach (var item in items)
{
parent.Items.Add(item);
}
items = null;
}
finally
{
if (items != null)
{
foreach (var item in items)
{
item.Dispose();
}
}
}
}
If an exception occurs after adding a number of the objects to the collection, I'll have a situation where the collection contains some disposed objects. Which could give rise to those disposed objects being disposed of again in the following try...catch block:
try
{
// Assume that menu.Items contains some items prior
// to the call to LoadMenuItems.
LoadMenuItems(menu);
}
catch
{
// The Dispose() iterates through menu.Items calling
// Dispose() on each.
menu.Dispose();
}
So what I am looking for possible solutions to stop Dispose() being called twice. I have a solution in mind, but thought I would give it to the community to see if there are any alternatives.
Upvotes: 4
Views: 2530
Reputation: 81347
Most cases where one might be worried about "accidentally" disposing an object multiple times come about because there is confusion about who "owns" the object in question, and such confusion will likely create other problems in addition to repeated disposal. While one could avoid having the multiple-disposal itself cause problems by having the disposal method use a flag so the second dispose attempt will return harmlessly, doing that without resolving the confusion about IDisposable ownership would not lave the more serious issues unresolved.
The primary scenarios where repeated disposal attempts should not be regarded as indicating broader problems are
Your scenario seems somewhat like the first one, except that it looks like you'll be disposing of each item after it gets added to parent.Items, which would suggest that you may have muddled issues of object ownership.
Upvotes: 2
Reputation: 273864
Which could give rise to those disposed objects being disposed of again
Which should be quite alright. The contract for Dispose() is very specific: it should be safe to call it multiple times.
But another way to get rid of it:
Analyzing your logic I would say the finally
part is superfluous, maybe the analyzer thinks so too. You really do solve the same problem twice.
Upvotes: 5