【问题标题】:C# Thread Static VariablesC# 线程静态变量
【发布时间】:2011-07-17 11:39:18
【问题描述】:

我有一个实现单例模式的静态 DataLibrary 类。

        public static FacilityRepository FacilRepo
        {
            get
            {
                if (_facilRepo == null)
                {
                    _facilRepo = new FacilityRepository(Authenticated.UserId);
                    if (Authenticated.FacKey.Length > 0)
                    {
                        foreach (var fac in _facilRepo)
                            fac.IsSelected = (fac.FacilityKey == Authenticated.FacKey);                        
                    }
                }
                return _facilRepo;
            }
        }

private static FacilityRepository _facilRepo;

当我使用 Task.Factory.StartNew 从不同的线程访问它时,FacilityReposity 会被重新创建多次,我该如何避免这种情况。

【问题讨论】:

  • 如果您同时创建许多新线程并且它们都试图访问 FacilRepo 属性。这可能是因为该属性周围没有锁定。看看en.csharp-online.net/…(右下角)

标签: c# multithreading static task


【解决方案1】:

我认为您实际上并没有在这里获得线程局部变量 - 您只是遇到了竞争条件,因为您没有正确实现单例模式。

我有一个page about the singleton pattern,它提供了一些更好的选择。 (特别是,当您使用 TPL 时,您必须使用 .NET 4,因此 Lazy<T> 选项绝对是一个竞争者。)

【讨论】:

  • 优秀的文章!!!!谢谢你 。等我再过 4 分钟,我会尽快接受你的回答。
【解决方案2】:

Jon Skeet 的这篇文章可能会有所帮助: Implementing the Singleton Pattern in C#

这些问题也可能会有所帮助:

【讨论】:

    【解决方案3】:

    如果多个线程在_facilRepo 初始化之前第一次访问您的属性,就会发生这种情况。您必须像这样锁定初始化代码:

    private static object _facilRepoLock = new object();
    public static FacilityRepository FacilRepo
    {
        get
        {
            if (_facilRepo == null)
            {
                lock (_facilRepoLock)
                {
                    if (_facilRepo == null)
                    {
                        _facilRepo = new FacilityRepository(Authenticated.UserId);
                        if (Authenticated.FacKey.Length > 0)
                        {
                            foreach (var fac in _facilRepo)
                                fac.IsSelected = (fac.FacilityKey == Authenticated.FacKey);
                        }
                    }
                }
            }
            return _facilRepo;
        }
    }
    
    private static FacilityRepository _facilRepo;
    

    【讨论】:

    • 如果变量不可变,我不确定这是否真的是线程安全的。有比使用双重检查锁定更简单的方法来实现线程安全。
    • 啊,有趣..我以前不知道..你的文章令人大开眼界:)
    猜你喜欢
    • 2013-03-29
    • 1970-01-01
    • 2011-06-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多