Ошибка «Значение не может быть пустым» в шаблоне Singleton - PullRequest
2 голосов
/ 08 марта 2011

У меня есть класс, который реализует шаблон синглтона, как вы можете видеть ниже:

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, чтобы приложение работало.Мы не можем воспроизвести ошибку на наших локальных серверах.Это просто происходит в производственной среде наших клиентов.

Как мы можем решить эту проблему и в чем причина этой странной ошибки?

Заранее спасибо,

1 Ответ

2 голосов
/ 08 марта 2011

Двойная проверка блокировки сломана .

Краткое объяснение:

Даже если foundation не равно нулю, без блокировки вы не можете быть уверенычлены этого фонда являются ненулевыми с точки зрения вашего процессора.

Вам необходимо удалить оператор if, находящийся за пределами блокировки.

Обновление

Лучшее решение - пометить фундамент как изменчивый:

private static volatile SearchSingletonObject foundation = null;

Потребность в модификаторе volatile при двойной проверке блокировки в .NET содержит более подробную информацию.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...