如何使此c#属性线程安全?
我有一些库实用程序,使事情变得简单一些如何使此c#属性线程安全?,c#,.net,properties,C#,.net,Properties,我有一些库实用程序,使事情变得简单一些 public static RequestUow Uow { get { return ContextItemsHelper.Get<RequestUow>("Uow"); } set { ContextItemsHelper.Set<RequestUow>("Uow", value); } } publicstaticrequestu
public static RequestUow Uow
{
get { return ContextItemsHelper.Get<RequestUow>("Uow"); }
set { ContextItemsHelper.Set<RequestUow>("Uow", value); }
}
publicstaticrequestuow-Uow
{
get{return ContextItemsHelper.get(“Uow”);}
set{ContextItemsHelper.set(“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; } }
publicstatict-Get(字符串键)
{
零空(key,“key”);
对象obj=项目[键];
返回obj.IsNotNull()?(T)obj:默认值(T);
}
静态IDictionary项{get{return HttpContextHelper.Current.Items;}}
这很好,但我现在想检查属性uow是否为null,是否设置了新的RequestUow并返回它
我看到的示例包括设置您自己的成员变量,但是我想知道这是否可能是线程安全的
有人有什么建议或解决方案吗?制作项目
a并使用它的方法。因为集合本身是线程安全的,所以您不必关心它
如果将您的更改为以下内容也会更好:
public static T Get<T>(string key)
{
Guard.NullOrEmpty(key, "key");
return Items.GetOrAdd( key, (key) => default(T) );
}
publicstatict-Get(字符串键)
{
零空(key,“key”);
返回项目.GetOrAdd(key,(key)=>default(T));
}
这样,在第一次尝试时添加默认值,如果再次调用,则返回默认值。使用模式只要字典没有变化(例如,没有更新),就可以访问它,它是完全线程安全的,没有任何附加措施(*)
请注意,如果包含的项本身不是线程安全的,那么为字典提供线程安全的getter/setter是没有帮助的。最安全的方法是使用字典中的不可变项;如果您的RequestUow
对象是可变的,那么您还需要使它们(以及使用此词典可能检索到的所有其他对象)成为线程安全的
*:有关.NET中线程安全集合的信息,请参见示例。第18页阐明了只读访问不需要额外的线程安全措施。这是最糟糕的模式之一。我同意,在使用该模式时需要非常小心。在使用之前,请阅读整篇文章。您还没有提供足够的代码让别人告诉您如何使此“线程安全”。首先,如果ContextItemsHelper
是公共的,则无法使Uow
属性线程安全,因为您不知道其他线程可能会使用ContextItemsHelper
执行什么操作。您可以尝试使ContextItemsHelper.Get
线程安全;但是如果其他代码使用了ContextItemsHelper.Items
属性,则会出现同样的问题。