长时间听众 - 第一次来电.我希望得到一些建议.我一直在阅读.net中的缓存 - 包括System.Web.Caching和System.Runtime.Caching.我想知道我可以获得什么额外的好处与简单地创建一个带锁定的静态变量.我目前的(简单的)缓存方法是这样的:
public class Cache
{
private static List<Category> _allCategories;
private static readonly object _lockObject = new object();
public static List<Category> AllCategories
{
get
{
lock (_lockObject)
{
if (_allCategories == null)
{
_allCategories = //DB CALL TO POPULATE
}
}
return _allCategories;
}
}
}
Run Code Online (Sandbox Code Playgroud)
除了到期(我不希望它到期)我不知道使用内置缓存的好处是什么.
也许对于不适用于我的更复杂的缓存方案有好处 - 或者我可能只是缺少某些东西(这不是第一次).
那么,如果我想要一个永不过期的缓存,使用缓存有什么好处?静态变量不这样做吗?
我在C#中有一个函数,可以从多个线程多次调用,我希望它只能完成一次,所以我想到了这个:
class MyClass
{
bool done = false;
public void DoSomething()
{
lock(this)
if(!done)
{
done = true;
_DoSomething();
}
}
}
Run Code Online (Sandbox Code Playgroud)
问题是_DoSomething需要很长时间,我不希望很多线程等待它,只要他们可以看到这done是真的.
这样的事情可以解决方法:
class MyClass
{
bool done = false;
public void DoSomething()
{
bool doIt = false;
lock(this)
if(!done)
doIt = done = true;
if(doIt)
_DoSomething();
}
}
Run Code Online (Sandbox Code Playgroud)
但只需手动锁定和解锁就会好得多.
我怎样才能手动锁定和解锁lock(object)?我需要它使用相同的接口,lock因此这种手动方式lock将相互阻塞(对于更复杂的情况).
使用这种模式有什么好处或原因?
public sealed class myStaticClass
{
private static bool _initialized;
private static object _lockObject;
private static string _someStaticField;
private static int _anotherStaticField;
private static string _nthStaticField;
static myStaticClass()
{
_initialized = false;
_lockObject = new object();
}
public myStaticClass()
{
}
public static void Initialize()
{
if(!_initialized)
{
lock(_lockObject)
{
if(!_initialized)
{
//do initializing
_someStaticField = someApplicationSetting;
_anotherStaticField = anotherApplicationSetting;
_nthStaticField = nthApplicationSetting;
_initialized = true;
}
}
}
}
public static string NthStaticField
{
get {
Initialize();
return _nthOtherField; …Run Code Online (Sandbox Code Playgroud) 框架:.net 4.5
我使用下面的示例代码模式以线程安全的方式初始化变量.最近我一直在阅读一些文章,这些文章解释了"在某些平台上已经破坏了双重检查锁定http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html "但看起来对我来说没问题.我正在使用.net 4.5.
根据评论提出建议
建议使用lazy并让.net框架在处理基于平台的线程安全和内存模型上做大量工作:):http://msdn.microsoft.com/en-us/library/dd642331.aspx
更新
似乎Eric Lippert一直建议不要使用这种模式(现在很困惑:() 这种模式的名称?(答案:使用双重检查锁定进行延迟初始化) C#手动锁定/解锁
更新2
下面的摘录是"像所有删除读锁的技术一样,图7中的代码(类似于我的代码)依赖于强写入顺序.例如,这个代码在ECMA内存模型中是不正确的,除非myValue变得易失,因为初始化LazyInitClass实例的写入可能会延迟到写入myValue之后,允许GetValue的客户端读取未初始化的状态.在.NET Framework 2.0模型中,代码在没有volatile声明的情况下工作.来自http://msdn.microsoft.com/en-us/magazine/cc163715.aspx
而且我也没有使用'volatile',因为许多示例都显示在不同的代码片段中.我也假设它也可以(参考:.NET中双重检查锁定需要volatile修饰符)
****psudeo代码 - 它解释了我正在使用的版本 - 构建于.net 4.5****之上
static private object s_syncObject = new object();
private static string s_lazyInitializedVariable = null;
//is it necessar to make the backing varible volatie?
//private static volatile string s_lazyInitializedVariable = null;
private static string LazyInitializedVariable
{
get
{
if(string.IsNullOrWhiteSpace(s_lazyInitializedVariable))
{
lock(s_syncObject)
{
if (string.IsNullOrWhiteSpace(s_lazyInitializedVariable))
{
/*
* my …Run Code Online (Sandbox Code Playgroud)