【问题标题】:How to have a singleton class and use it through out the application c#如何拥有一个单例类并在整个应用程序中使用它 c#
【发布时间】:2021-04-08 10:18:42
【问题描述】:

我有一个反序列化 JSON 文件的类。 JSON 是 styleconfig.json

    {  
        "Style1": {  
            "Font":       "Arial",   
            "width":      "25px",   
            "className":    "Grid-side"
        }  ,
"Style2": {  
            "Font":       "Arial",   
            "width":      "25px",   
            "className":    "Grid-side"
        }  
    }  

我有一个A类:

 var jss = new JavaScriptSerializer();
string json = new StreamReader(context.Request.InputStream).ReadToEnd();
Dictionary<string, string> sData = jss.Deserialize<Dictionary<string, string>>(json);

所以我每次都需要在我的应用程序中调用这个 classA 例如 有两页... Page1 和 page2 两个样式变量都在 json 上 所以每次我需要调用classA来反序列化

  1. page1 调用 classA 进行反序列化
  2. page2 调用 classA 进行反序列化

所以这可能会影响性能。最终,整个应用程序的 JSON 文件是相同的

所以我的要求是只在我登录应用程序时运行一次 classA 并制作 整个应用程序中的反序列化 JSON 对象。 我需要一些帮助

【问题讨论】:

    标签: c# json serialization singleton global


    【解决方案1】:

    您可以使用静态类执行此操作并使用 Lazy 来确保它只加载一次:

    public static class A
    {
        private static Lazy<Dictionary<string, string>> _data = new Lazy<Dictionary<string, string>>(() => GetData());
    
        public static Dictionary<string, string> Data => _data.Value;
    
        private static Dictionary<string, string> GetData()
        {
            var jss = new JavaScriptSerializer();
            string json = new StreamReader(context.Request.InputStream).ReadToEnd();
            return jss.Deserialize<Dictionary<string, string>>(json);
        }
    }
    

    【讨论】:

      【解决方案2】:

      您应该为此使用Lazy<T>。这是一个例子:

      static class ClassA 
      {
          private static Lazy<Dictionary<string, string>> _json = new Lazy<Dictionary<string, string>>(ReadJson);
      
          private static Dictionary<string, string> ReadJson()
          {
              var jss = new JavaScriptSerializer();
              var json = new StreamReader(context.Request.InputStream).ReadToEnd();
              return jss.Deserialize<Dictionary<string, string>>(json);
          }
      
          public Dictionary<string, string> Json => _json.Value;
      
      }
      

      现在,当您第一次读取ClassA.Json 时,该文件将被解析和读取。后续调用只会返回缓存的值。

      【讨论】:

      • 在此,我有一个带有参数的方法 ReadJson(),例如 Readjson(int a)。所以我无法使用上面的方法。谢谢你的回复真的很有帮助。 @torvin
      【解决方案3】:

      如果我正确理解了您的问题,除了已经在其他 cmets 中解释过的惰性字段之外,您是否尝试过简单的属性?

       public class ClassA
          {
              //Just a singleton model
              static ClassA _SingleInstance = null;
              public static ClassA SingleInstance
              {
                  get
                  {
                      if (_SingleInstance == null)
                          _SingleInstance = new ClassA();
      
                      return _SingleInstance;
                  }
              }
      
              Dictionary<string, string> _Data = null;
              public Dictionary<string, string> Data
              {
                  get
                  {
                      if (_Data == null)
                          LoadData();
                      return _Data;
                  }
              }
      
            
              private ClassA()
              {
                  //your constructor
              }
              
              //As pointed out by torvin, to avoid multithread races, load must
              //be synchronized
              private void LoadData()
              {
                  lock(LoadMutex)
                  {
                      if (_Data == null)
                      {
                          var jss = new JavaScriptSerializer();
                          string json = new StreamReader(context.Request.InputStream).ReadToEnd();
                          _Data = jss.Deserialize<Dictionary<string, string>>(json);
                      }
                  }
              }
      
              private static readonly object LoadMutex = new object();
      
          }
      
      

      然后从Page1和Page2,你调用它:

      
          Dictionary<string, string> myConfigData = ClassA.SingleInstance.Data;
      

      【讨论】:

      • 使用“简单属性”与使用Lazy 的缺点是它不是线程安全的,它可以调用LoadData 两次,这可能是不可取的
      • 你是完全正确的,它应该使用一些互斥同步。我编辑我的答案
      • 不,您应该使用专门为此用例制作的Lazy&lt;&gt;
      猜你喜欢
      • 2014-05-31
      • 2014-08-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-05-29
      • 1970-01-01
      • 2011-03-19
      相关资源
      最近更新 更多