我目前正在开发“Singleton”类,但它不仅要承受线程安全性,因为我不仅要访问它,还需要设置一些内容。.我想知道如何做到这一点-似乎用当我不知道lock(object)的实际作用以及是否必须使每个方法的线程安全时,ojit_code会感到有些hacky?

到目前为止,我已经有了这个非线程安全的代码-因为在每个线程中都应该访问相同的数据。我如何最好地使它成为线程安全并保持单例状态?

public class AppSession() {
    private static AppSession _instance = new AppSession();
    public static AppSession Instance { get { return _instance; } }

    private AppSession() { }

    private string _actionName = "none";
    private DateTime? _actionTime = null;
    public void ActionExecuted(string action) {
        _actionName = action ?? String.Empty;
        _actionTime = DateTime.UtcNow;
    }

    public LastAction {
       get { return $"{_action} at {_actionTime?.Value.ToString()}"; }
    }
}

最佳答案

  • 首先,我将从让您的Singleton适应使用.NET库中的Lazy<T>类开始。 MSDN文档指出,“ Lazy<T> 提供了对延迟初始化的支持”,它还提供了a bool parameter isThreadSafe,当它为true时,“使得实例可以由多线程并行使用”。
    private static Lazy<AppSession> _instance =
    new Lazy<AppSession>(
        () => new LazyAppsession(), isThreadSafe: true
    );
    
  • 其次,我还将Lazy<AppSession>也标记为readonly,这样,任何方法或代码都无法覆盖_instance字段的值。
  • 至于ActionExecuted方法,我不知道您是否仍然需要通过锁定该线程来使其安全。可以扩展我的答案-我也想知道自己!

  • 这样,您的类将看起来像这样-但是我不确定ActionExecuted方法,而且正如我所说,我所知道的唯一可以理解这一点的人就是@JonSkeet。
    public class AppSession() {
        private static readonly Lazy<AppSession> _instance =
            new Lazy<AppSession>(
                () => new LazyAppsession(), isThreadSafe: true
            );
        public static AppSession Instance {
            get { return _instance.Value; }
        }
    
        private AppSession() { }
    
        private string _actionName = "none";
        private DateTime? _actionTime = null;
        public void ActionExecuted(string action) {
            _actionName = action ?? String.Empty;
            _actionTime = DateTime.UtcNow;
        }
    }
    

    10-06 02:43