【问题标题】:"Value can not be null" error in Singleton pattern单例模式中的“值不能为空”错误
【发布时间】:2011-03-08 12:22:39
【问题描述】:

我有一个实现单例模式的类,如下所示:

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,才能使应用程序正常工作。我们无法在本地服务器上重现该错误。它只发生在我们客户的生产环境中。

我们如何解决这个问题?这个奇怪错误的原因是什么?

提前致谢,

【问题讨论】:

标签: c# wcf design-patterns singleton


【解决方案1】:

Double-checked locking is broken.

简短说明:

即使foundation 是非空的,如果没有锁,从处理器的角度来看,您也无法确定基金会的成员是非空的。

您需要删除锁外的 if 语句。

更新

更好的解决方案是将基础标记为 volatile:

private static volatile SearchSingletonObject foundation = null;

The need for volatile modifier in double checked locking in .NET 有更多详细信息。

【讨论】:

  • 感谢您有说服力的回答 arx。今晚我们将按照您所说的方式发布我们的服务。
  • 这种模式在 Java 中被破坏了,并且由于 Java 的特定原因。这是 C#,在 .NET 上,所以这不能回答问题。
  • 它在 Java 中已损坏,在 C# 中已损坏。更多细节在这里:stackoverflow.com/questions/1964731/…
猜你喜欢
  • 2015-11-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-30
  • 2017-12-16
  • 1970-01-01
  • 2012-07-22
  • 2021-12-09
相关资源
最近更新 更多