加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – 是否可以使用Hashtable作为锁定对象?

发布时间:2020-12-16 00:24:52 所属栏目:百科 来源:网络整理
导读:我有以下代码,其中“_ht”是表示缓存的Hashtable,“_ isLoaded”表示它是否已加载. 我们的系统有许多进程访问“_ht”对象,我需要它们等待它没有加载. 使用“_ht”作为锁定对象是错误的吗?我应该为此方案使用专用的对象类型类成员吗? 重要的是要提到这个班
我有以下代码,其中“_ht”是表示缓存的Hashtable,“_ isLoaded”表示它是否已加载.

我们的系统有许多进程访问“_ht”对象,我需要它们等待它没有加载.

使用“_ht”作为锁定对象是错误的吗?我应该为此方案使用专用的对象类型类成员吗?

重要的是要提到这个班级是SINGLETON.

private Hashtable _ht = new Hashtable();
private bool _isLoaded = false;

internal Hashtable GetHT()
        {
            if (_isLoaded == false)
            {
                lock (_ht)
                {
                    if (_isLoaded == false)
                    {
                        LoadHt(_ht);
                    }
                }
            }

            return _ht;
        }

解决方法

您当然可以锁定Hashtable对象,就像在lock语句中使用.NET中的任何引用类型实例一样.但是,它通常被认为是一种较差的方法,主要是因为当一个或多个锁定对象可用于代码的其他部分时,很难跟踪代码如何使用锁定,他们也可能将其用于锁定(再次,不可思议,但你会惊讶于人们有时写的代码).

通常,对于锁定,优选单独的锁定对象.我会注意到在你的代码示例中,_ht应该是只读的,如果你添加一个单独的锁定对象(例如lockObj),那也应该是readonly.

也就是说,单身场景不应该以这种方式实现.相反,您应该使用CLR自己的静态初始化,或者使用Lazy< T>.类:

private static readonly Hashtable _ht = InitializeTable();

internal static Hashtable GetHT() { return _ht; }

private static Hashtable InitializeTable()
{
    Hashtable table = new Hashtable();

    LoadHt(table);

    return table;
}

要么:

private static readonly Lazy<Hashtable> _ht = new Lazy<Hashtable>(() => InitializeTable());

internal static Hashtable GetHT() { return _ht.Value; }

private static Hashtable InitializeTable()
{
    Hashtable table = new Hashtable();

    LoadHt(table);

    return table;
}

当你有可能被访问的类型的其他成员时,后者很有用,但是你想确保哈希表的初始化尽可能延迟(例如,如果可能没有代码实际访问它,那么你可以避免完全初始化它).

(我将所有内容都更改为静态,因为您将场景描述为单例,在这种情况下,只有静态成员才能对代码示例有意义).

最后我会注意到Hashtable类非常过时.作为一个非泛型类,您真的应该认真考虑升级代码以使用现在已经十年的泛型类型.字典< TKey,TValue> class是最直接的替换,但人们有时使用Hashtable作为简单集合,其中HashSet< T>数据结构会更合适.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读