2013-03-01 58 views
-1

我有一個名爲「LogLevels」的公共屬性的靜態類「Logger」,如下面的代碼所示。同時使用靜態類中的靜態屬性

當在多用戶或多線程環境中同時使用該屬性時,它是否會導致問題?

我需要使用線程同步作爲屬性「LogLevels」中的代碼嗎?

public class Logger 
{ 
    private static List<LogLevel> _logLevels = null; 


    public static List<LogLevel> LogLevels 
    { 
     get 
     { 
      if (_logLevels == null) 
      { 
       _logLevels = new List<LogLevel>(); 
       if (!string.IsNullOrWhiteSpace(System.Configuration.ConfigurationManager.AppSettings["LogLevels"])) 
       { 

        string[] lls = System.Configuration.ConfigurationManager.AppSettings["LogLevels"].Split(",".ToCharArray()); 
        foreach (string ll in lls) 
        { 

         _logLevels.Add((LogLevel)System.Enum.Parse(typeof(LogLevel), ll)); 
        } 
       } 
      } 

      if (_logLevels.Count == 0) 
      { 
       _logLevels.Add(LogLevel.Error); 
      } 
      return _logLevels; 
     } 
    } 
} 

更新:我結束了使用線程同步解決併發問題的一個靜態類,如下面的代碼。

public class Logger 
{ 
    private static readonly System.Object _object = new System.Object(); 

    private static List<LogLevel> _logLevels = null; 


private static List<LogLevel> LogLevels 
    { 
     get 
     { 
      //Make sure that in a multi-threaded or multi-user scenario, we do not run into concurrency issues with this code. 
      lock (_object) 
      { 
       if (_logLevels == null) 
       { 
        _logLevels = new List<LogLevel>(); 
        if (!string.IsNullOrWhiteSpace(System.Configuration.ConfigurationManager.AppSettings["SimpleDBLogLevelsLogger"])) 
        { 

         string[] lls = System.Configuration.ConfigurationManager.AppSettings["SimpleDBLogLevelsLogger"].Split(",".ToCharArray()); 
         foreach (string ll in lls) 
         { 

          _logLevels.Add((LogLevel)System.Enum.Parse(typeof(LogLevel), ll)); 
         } 
        } 
       } 

       if (_logLevels.Count == 0) 
       { 
        _logLevels.Add(LogLevel.Error); 
       } 
      } 
      return _logLevels; 
     } 
    } 
} 
+0

您的房產在您的示例中是「private」,而不是「public」 – JerKimball 2013-03-01 18:38:08

+0

我已更正修改並將其更改爲public。 – Sunil 2013-03-01 21:38:29

回答

3

當屬性在多用戶或多線程環境中同時使用,可它引起的問題?

絕對。 List<T>不適用於多線程,除了只是多個閱讀器(無編寫者)的情況。

是否需要使用屬性LogLevels中代碼的線程同步?

那麼這是一種方法。或者只是在初始化類型時初始化它,然後返回一個只讀包裝器。 (你真的不希望多線程修改它。)

請注意,通常,在靜態構造函數中執行大量工作是bad idea。你是否滿意,如果失敗了,每一次訪問這個屬性都會失敗,直到永遠?

+0

...除非沒有人可以訪問它(我認爲他的意思是公開的,而不是私有的) – JerKimball 2013-03-01 18:38:45

+0

Jon - 所以,你說要麼使用線程同步,要麼將屬性代碼轉移給這個類的靜態構造函數。對?或者你的意思是別的? – Sunil 2013-03-01 18:45:53

+0

@Sunil:是的,但最重要的是返回一個只讀包裝。 – 2013-03-01 18:47:20

3

此代碼擁有競爭條件,不能安全地從多個線程執行。主要問題是List<T>類型不是線程安全的,但此代碼將自由寫入。這意味着寫入可以並行發生,因此打破隱式合約List<T>

1

簡短答案是「是」和「是」您確實需要線程同步。另一個問題是,爲什麼重新發明輪子?你可以使用類似log4net或.NET日誌框架的東西。

+0

所有這些日誌框架的問題是陡峭的學習曲線。我希望我的開發人員從第1天開始記錄,並且我只想記錄到數據庫。 – Sunil 2013-03-01 20:11:53

+0

你可以慢慢來。例如,log4net的基本功能及其基本配置相對簡單,甚至新手也可以在幾個小時內開始使用它。或者你可以在lon4net上創建一個簡化的包裝,這會隱藏配置的複雜性, – user1873415 2013-03-01 20:25:04