【发布时间】:2013-12-19 19:25:27
【问题描述】:
以下胎面在单例模式中是否安全?我在http://csharpindepth.com/Articles/General/Singleton.aspx中使用了第四个单例模式
我担心使用输出参数会破坏整个主体。
public sealed class eCacheContent
{
private static readonly eCacheContent instance = new eCacheContent();
private ICacheManager _Cache = CacheFactory.GetCacheManager(ConfigurationManager.AppSettings["ContentCache"].ToString());
// for access method control locking
private static object syncRoot = new object();
// Explicit static constructor to tell C# compiler
// not to mark type as beforefieldinit
static eCacheContent() { }
private eCacheContent() { }
public static eCacheContent Instance
{
get
{
return instance;
}
}
public bool TryGetValue(string key, out eContent output)
{
lock (syncRoot)
{
if (Contains(key))
{
ObjectCloner helper = new ObjectCloner();
eContent tmp = (eContent)this._Cache.GetData(key);
output = helper.Clone(tmp);
return true;
}
output = new eContent();
return false;
}
}
public void Add(string key, object value)
{
// Initiase the helper class for cloning
if (CheckKeyIfValid(key))
{
ObjectCloner helper = new ObjectCloner();
// Remove if already exist
this.Remove(key);
// Add carbon copy
_Cache.Add(key, helper.Clone(value));
}
}
public void Flush()
{
_Cache.Flush();
}
private bool Contains(string key)
{
if (CheckKeyIfValid(key))
return _Cache.Contains(key);
else
return false;
}
private void Remove(string key)
{
if (Contains(key))
{
_Cache.Remove(key);
}
}
private bool CheckKeyIfValid(string key)
{
if ((key != null) && (key.Trim().Length != 0))
return true;
return false;
}
}
【问题讨论】:
-
您的方法是 instance 方法,而不是
static- 我认为这是一个错误? -
我会说这确实是个坏主意。当您锁定此代码时,可能有其他线程正在访问您的“out”-ed 变量。切勿尝试锁定此 var,因为这可能会导致死锁。所以我会说:坏主意。无论如何,为什么要使用 ref 呢?只需返回字符串。这不是 c++,成员是引用计数的。
-
我知道我的想法哪里出了问题。看看外面总是有帮助的......谢谢
-
@Samuel OP 并未锁定该变量,但他们有一个特定的
syncRoot对象用于锁定。 “这不是 C++,成员被引用计数” - 这也不准确,C#不使用引用计数,GC 在收集期间遍历对象图并处理任何无法到达的对象。 -
@James 感谢您指出这一点。我实际上知道 GC 会删除所有非根对象。但恕我直言,在更广泛的意义上,这可以被视为引用计数,其中引用表示根对象的任何路径(计数为 1),如果没有,则为 0:/ 但你是对的,我的解释不好。