“值不能为空”单例模式中的错误
我有一个实现单例模式的类,如下所示:
public class SearchSingletonObject
{
private static SearchSingletonObject foundation = null;
public SearchObject Object= null;
private static StringCollection views = null;
private static object control = new object();
public IEnumerable<string> blacklist = null;
public static void ClearFoundation()
{
foundation = null;
}
public static SearchSingletonObject Foundation
{
get
{
if (foundation == null)
{
lock (control)
{
if (foundation == null)
{
foundation = new SearchSingletonObject();
var blacks = File.ReadAllText(HostingEnvironment.ApplicationPhysicalPath + "\\blacklist.txt");
foundation.blacklist = blacks.Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries).Where(x => !string.IsNullOrEmpty(x) || x != " ");
views = new StringCollection();
var items = ConfigurationManager.AppSettings["SearchView"].Split(',');
foreach (var item in items)
{
views.Add(item);
}
foundation.Object = new SearchObject(ConfigurationManager.AppSettings["ContentDistributor"],
ConfigurationManager.AppSettings["Port"],
views);
}
}
}
return foundation;
}
}
public SearchSingletonObject()
{
}
}
我们在 wcf 休息服务中使用此类。但在非周期性间隔中,我们会收到“值不能为空”错误。这是我的日志文件:
08.03.2011 11:40:39 ERROR Message : Value cannot be null.
Parameter name: source
StackTrace : at System.Linq.Enumerable.Where[TSource](IEnumerable`1 source, Func`2 predicate)
at Search.Service.SearchService.Search(String keyword, Int32 offset, Int32 hit, String navstate, String username, Boolean issecure, Int32 suggest, String sortref, String fields, Int32 IsFirstSearch, String misspelled, String category) in D:\tfs\Hey\HeyRestApi\HeyService\HeyService.cs:line 68
日志文件提到了我的服务中的以下行:
var blacks = SearchSingletonObject.Foundation.blacklist.Where<string>(x => item.Equals(x)).FirstOrDefault();
“黑名单”对象获取空值似乎很奇怪。错误发生后,我们必须重置 IIS,以使应用程序正常工作。我们无法在本地服务器上重现该错误。它只发生在我们客户的生产环境中。
我们如何解决这个问题以及这个奇怪错误的原因是什么?
提前致谢,
I have a class that implements singleton pattern as you can see below:
public class SearchSingletonObject
{
private static SearchSingletonObject foundation = null;
public SearchObject Object= null;
private static StringCollection views = null;
private static object control = new object();
public IEnumerable<string> blacklist = null;
public static void ClearFoundation()
{
foundation = null;
}
public static SearchSingletonObject Foundation
{
get
{
if (foundation == null)
{
lock (control)
{
if (foundation == null)
{
foundation = new SearchSingletonObject();
var blacks = File.ReadAllText(HostingEnvironment.ApplicationPhysicalPath + "\\blacklist.txt");
foundation.blacklist = blacks.Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries).Where(x => !string.IsNullOrEmpty(x) || x != " ");
views = new StringCollection();
var items = ConfigurationManager.AppSettings["SearchView"].Split(',');
foreach (var item in items)
{
views.Add(item);
}
foundation.Object = new SearchObject(ConfigurationManager.AppSettings["ContentDistributor"],
ConfigurationManager.AppSettings["Port"],
views);
}
}
}
return foundation;
}
}
public SearchSingletonObject()
{
}
}
We're using this class in our wcf rest services. But in non-periodic intervals we get "Value can not be null" errors. Here is my log file:
08.03.2011 11:40:39 ERROR Message : Value cannot be null.
Parameter name: source
StackTrace : at System.Linq.Enumerable.Where[TSource](IEnumerable`1 source, Func`2 predicate)
at Search.Service.SearchService.Search(String keyword, Int32 offset, Int32 hit, String navstate, String username, Boolean issecure, Int32 suggest, String sortref, String fields, Int32 IsFirstSearch, String misspelled, String category) in D:\tfs\Hey\HeyRestApi\HeyService\HeyService.cs:line 68
Log file mentions the row below in my service:
var blacks = SearchSingletonObject.Foundation.blacklist.Where<string>(x => item.Equals(x)).FirstOrDefault();
It seems strangely the "blacklist" object getting null value. After the error, we have to reset IIS, to get application working. We can not reproduce the error on our local servers. It just happens in our customers production environment.
How can we solve that problem and what can be the reason of this strange error?
Thanks in advance,
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
双重检查锁定已损坏。
简短说明:
即使
foundation
为非空,在没有锁的情况下,从处理器的角度来看,您也无法确定 Foundation 的成员为非空。您需要删除锁之外的 if 语句。
更新
更好的解决方案是将基础标记为易失性:
.NET 中双重检查锁定中需要 volatile 修饰符 有更多详细信息。
Double-checked locking is broken.
Short explanation:
Even if
foundation
is non-null, without a lock you can't be sure that foundation's members are non-null from the point of view of your processor.You need to remove the if statement that's outside the lock.
Update
A better solution is to mark foundation as volatile:
The need for volatile modifier in double checked locking in .NET has more details.