2011-03-08 36 views
2

的錯誤,我有一個實現單件模式的類,你可以看到如下:「值不能爲空」在Singleton模式

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 REST服務。但是在非週期性時間間隔中,我們得到「值不能爲空」的錯誤。這是我的日誌文件:

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,才能使應用程序正常工作。我們無法在本地服務器上重現錯誤。它只發生在我們的客戶生產環境中。

我們該如何解決這個問題以及這個奇怪錯誤的原因是什麼?

在此先感謝,

+0

爲什麼不完全避免這種模式?請參閱http://stackoverflow.com/questions/162042/are-there-any-viable-alternatives-to-the-gof-singleton-pattern – TrueWill 2011-03-08 13:52:28

回答

2

Double-checked locking is broken

簡短說明:

即使foundation非空,沒有你不能確保基金會的成員是來自來看你的處理器的點非空的鎖。

您需要刪除鎖之外的if語句。

更新

更好的解決方案是,以紀念基金會揮發性:

private static volatile SearchSingletonObject foundation = null; 

The need for volatile modifier in double checked locking in .NET有更多的細節。

+0

感謝您的說服性答案arx。今晚我們將按照您告訴的方式發佈我們的服務。 – anilca 2011-03-08 13:02:41

+0

該模式在Java中被破壞,並且出於Java特定的原因。這是.NET上的C#,所以這不能回答這個問題。 – 2011-03-08 13:23:28

+1

它在Java中被破解並且在C#中被破壞。更多細節在這裏:http://stackoverflow.com/questions/1964731/the-need-for-volatile-modifier-in-double-checked-locking-in-net – arx 2011-03-08 13:34:22