如何在字典中处理一次性资源

3
我们有一些数据源类来处理一次性资源的操作,就像这样:

(译注:指实现了 IDisposable 接口的类)

public class SomeDataStore
{
    private readonly object dictionaryLock = new object();

    private readonly Dictionary<uint, SomeDisposableClass> dataStore = new Dictionary<uint, SomeDisposableClass>();

    public bool Remove(uint key)
    {
        bool returnValue = false;

        lock (dictionaryLock)
        {
            returnValue = dataStore.Remove(key);
        }

        //OR...

        lock (dictionaryLock)
        {
            SomeDisposableClass element;

            if (dataStore.TryGetValue(key, out element))
            {
                element.Dispose();
                returnValue = dataStore.Remove(key);
            }
        }

        return returnValue;
    }

    public void Clear()
    {
        lock (dictionaryLock)
        {
            dataStore.Clear();
        }

        //OR...

        lock (dictionaryLock)
        {
            foreach (var value in dataStore.Values)
                value.Dispose();

            dataStore.Clear();
        }
    }

    //Some other Datastore access members
}

public class SomeDisposableClass : IDisposable
{
    public void Dispose()
    {
        //Dispose resources..
    }
}

不确定哪个版本更好以及为什么?DictionaryClear 或者 Remove 内部是否处理 disposable 资源?


5
通常调用对象的 Dispose 方法的代码是创建该对象的代码。SomeDataStore 假定拥有该对象的所有权是有一定风险的。很难确定,因为你的代码中没有显示添加对象,更不用说是谁创建了它了。 - user585968
不,删除(无论是通过“Remove”还是“Clear”或其他方式)都不会调用dipose,当完成时必须自行处理。 - MakePeaceGreatAgain
4
你可以考虑使用ConcurrentDictionary替代带有lockDictionary,这样可以更好地处理线程安全问题。不过这并不能解决你目前的问题。 - mjwills
如果该方法确实调用了 Dispose,我希望该方法能更清晰地表达其意图,例如 RemoveAndDispose。或者,让 Remove 返回 SomeDisposableClass,这样调用者就可以使用 SomeDataStore.Remove(key)?.Dispose()(如果他们愿意的话)。 - mjwills
1
这取决于这个类被如何使用。例如,如果我将我的对象放入字典中,然后将其移除并通过这种方式处理它,那么我会感到非常惊讶。然而,在您的情况下,这可能正是所期望的。 - Evk
2个回答

5
当从字典中删除元素时,为什么应该自动处理它?无论如何,它可能存在于另一个列表或其他地方。话虽如此,在某些集合中删除对象时进行处理是非常危险的。您提到的所有方法(RemoveClear等)都不知道可处理的对象。所有这些方法所做的只是从内部缓存中删除对您实例的引用。然而,删除对象的引用并不意味着它应该被释放(GC)甚至处理(IDisposable)。事实上,这与可处理的对象无关。即使在另一个列表中存在对其的引用,GC也不会释放您的对象。
因此,您应该始终在控制它们的地方处置资源 - 这通常是在创建它们的相同上下文中。

2
不,您应该自己处理一次性对象。字典不会处理这个。
就像Micky所说的那样,只有当它拥有对象时才能处理。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接