我有一个一次性物品清单,我将其添加到已包含许多一次性物品的集合中。我将代码包装在try ... finally块中,这样如果在我将列表中的项目复制到集合时抛出异常,则列表中的所有对象都将被正确处理:
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();
}
}
}
}
如果在将多个对象添加到集合后发生异常,我将遇到集合包含一些已处置对象的情况。这可能会导致那些被处置的物体再次被丢弃在下面的尝试...抓住块:
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();
}
所以我正在寻找可能的解决方案来阻止Dispose()被调用两次。我有一个解决方案,但我想我会把它交给社区,看看是否有其他选择。
答案 0 :(得分:5)
这可能会导致那些被处置的物体再次被丢弃
哪个应该没问题。 Dispose()的合同非常具体:多次调用它应该是安全的。
但摆脱它的另一种方法是:
分析你的逻辑我会说finally
部分是多余的,也许分析师也这么认为。你确实两次解决同样的问题。
答案 1 :(得分:2)
大多数情况下,人们可能会担心“意外”多次处理一个物体,因为对于“拥有”有关物体的人存在混淆,这种混淆可能会产生除重复处置之外的其他问题。虽然可以通过处置方法使用标志来避免多重处置本身导致问题,因此第二次处置尝试将无害地返回,这样做而不解决关于IDisposable所有权的混淆不会导致更严重的问题未解决。
不应将重复处置企图视为表明更广泛问题的主要方案是
你的场景看起来有点像第一个,除了看起来你将在将每个项目添加到parent.Items之后处理它们,这表明你可能会混淆对象所有权问题。