如何使这个c#属性线程安全?

时间:2012-09-07 13:57:19

标签: c# .net properties

我有一些库实用程序可以使事情变得更简单。

        public static RequestUow Uow
        {
            get { return ContextItemsHelper.Get<RequestUow>("Uow"); }
            set { ContextItemsHelper.Set<RequestUow>("Uow", value); }
        }

在ContextItemsHelper

    public static T Get<T>(string key)
    {
        Guard.NullOrEmpty(key, "key");

        object obj = Items[key];

        return obj.IsNotNull() ? (T)obj : default(T);
    }

    static IDictionary Items { get { return HttpContextHelper.Current.Items; } }

这很好但我现在想检查属性uow是否为null,如果它设置了一个新的RequestUow并返回它。

我见过的例子涉及设置你自己的成员变量,但是我想知道这是否可能是线程安全的。

有人提供任何建议或解决方案吗?

3 个答案:

答案 0 :(得分:3)

Items设为ConcurrentDictionary并使用AddOrUpdate方法。由于集合本身是线程安全的,因此您无需关心它。

如果您的Get更改为此类内容也会更好:

public static T Get<T>(string key)
{
    Guard.NullOrEmpty(key, "key");
    return Items.GetOrAdd( key, (key) => default(T) );
}

这样,默认值会在第一次尝试时添加,如果再次调用则会返回。

答案 1 :(得分:0)

答案 2 :(得分:0)

只要字典没有变异(例如没有更新),访问它是完全线程安全的,没有任何额外的措施(*)。

请注意,如果包含的项目本身不是线程安全,则为字典设置threadsafe getter / setter没有帮助。最安全的赌注是在字典中使用不可变项;如果你的RequestUow对象是可变的,那么你需要创建它们(以及可能使用这个字典检索的所有其他东西)线程安全。

*:有关.NET中线程安全集合的信息,请参阅例如this PDF。第18页阐明了只读访问不需要额外测量线程安全性。