-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;
        }
    }
}
4

3 に答える 3

3

マルチユーザー環境またはマルチスレッド環境でプロパティを同時に使用すると、問題が発生する可能性がありますか?

絶対。複数のリーダーだけが存在する(ライターList<T>が存在しない) 場合を除いて、複数のスレッド用に設計されていません。

プロパティ「LogLevels」内のコードにスレッド同期を使用する必要がありますか?

まあ、それは1つのアプローチです。または、型の初期化時に初期化してから、読み取り専用のラッパーを返します。(実際には、複数のスレッドで変更する必要はありません。)

一般に、静的コンストラクターで大量の作業を行うことは悪い考えであることに注意してください。これが失敗した場合、このプロパティへのすべてのアクセスが永遠に失敗することに満足していますか?

于 2013-03-01T18:37:56.187 に答える
3

このコードには競合状態があり、複数のスレッドから安全に実行することはできません。主な問題は、List<T>型がスレッド セーフではないにもかかわらず、このコードが自由に書き込みできることです。これは、書き込みが並行して発生する可能性があることを意味し、したがって、List<T>

于 2013-03-01T18:38:49.743 に答える
1

簡単な答えは「はい」と「はい」で、スレッドの同期が必要です。もう 1 つの質問は、なぜ車輪を再発明するのかということです。log4net や .NET ロギング フレームワークなどを使用できます。

于 2013-03-01T18:39:52.550 に答える