C#线程静态变量

时间:2011-03-17 15:00:38

标签: c# multithreading static task

我有一个实现单例模式的静态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会多次重新创建,我该怎样才能避免这种情况。

3 个答案:

答案 0 :(得分:9)

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

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

答案 1 :(得分:1)

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

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

答案 2 :(得分:0)

如果多个线程在初始化_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;