我有以下单例类,它用作在我的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
答案 0 :(得分:1)
您的代码几乎与MSDN article上讨论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;
}
}
}
我没有编译这段代码,更不用说对它进行压力测试了。如果你试试,请告诉我这是否有效!