1

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

        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 是否为空,是否设置了新的 RequestUow 并返回它。

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

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

4

3 回答 3

3

制作Items一个ConcurrentDictionary并使用它的AddOrUpdate方法。由于集合本身是线程安全的,因此您不必关心它。

Get如果您更改为这样的内容也会更好:

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

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

于 2012-09-07T14:01:18.880 回答
0

使用模式双重检查锁定模式

于 2012-09-07T14:01:49.270 回答
0

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

请注意,如果包含的项目本身不是线程安全的,则为字典提供线程安全的 getter/setter 并没有帮助。最安全的选择是使用字典中的不可变项;如果您的RequestUow对象是可变的,那么您还需要使它们(以及可能使用此字典检索的所有其他内容)成为线程安全的。

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

于 2012-09-07T14:05:30.443 回答