ASP.NET MVC竞争条件?Factory Singleton静态字典

本文关键字:Factory Singleton 静态 字典 条件 NET MVC 竞争 ASP | 更新日期: 2023-09-27 18:20:35

我有下面的singleton类,它是在web应用程序中创建对象的工厂。然而,我看到我在负载测试中遇到了某种比赛状态。有没有更好的模式我应该遵循?

public class SearchProviderFactory {
    private static SearchProviderFactory factory = null;        
    private static Dictionary<string, Type> providerMap = new Dictionary<string, Type>();
    private SearchProviderFactory() {
        // Error on the line below
        providerMap.Add("company_name", Type.GetType("MyApp.CompanySearchProvider"));
        providerMap.Add("job_title", Type.GetType("MyApp.JobTitleSearchProvider"));
    }
    public static SearchProviderFactory Instance {
        get {
            if (factory == null) {
                factory = new SearchProviderFactory();
            }
            return factory;
        }
    }
}

我得到了以下错误,尽管私有构造函数似乎永远不应该被调用不止一次。

System.ArgumentException: An item with the same key has already been added.
   at System.Collections.Generic.Dictionary`2.Insert(TKey key, TValue value, Boolean add)
   at MyApp.SearchProviderFactory..ctor() in c:'MyApp'_scm'app'src'trunk'MyApp'SearchProviderFactory.cs:line 7

ASP.NET MVC竞争条件?Factory Singleton静态字典

您的代码与MSDN文章中讨论C#中Singleton实现的示例代码几乎相同。那篇文章很好看,我推荐它。

他们的建议是添加一个lock()语句来实现一个关键部分,在代码中使用

public class SearchProviderFactory {
    private static volatile SearchProviderFactory factory;        
    private static Dictionary<string, Type> providerMap = new Dictionary<string, Type>();
    private SearchProviderFactory() {
        // Error on the line below
        providerMap.Add("company_name", Type.GetType("MyApp.CompanySearchProvider"));
        providerMap.Add("job_title", Type.GetType("MyApp.JobTitleSearchProvider"));
    }
    public static SearchProviderFactory Instance {
        get {
            if (factory == null) {
                lock (providerMap)
                {
                    if (factory == null) {
                        factory = new SearchProviderFactory();
                    }
                }
            }
            return factory;
        }
    }
}

我没有编译这个代码,更不用说对它进行压力测试了。如果你尝试过,请告诉我这是否有效!