2014-09-03 2 views
1

웹 응용 프로그램에서 객체를 만들기위한 팩토리로 사용되는 다음 싱글 톤 클래스가 있습니다. 그러나로드 테스트 중에 어떤 종류의 경쟁 조건이 발생하는 것을보고 있습니다. 따라야 할 더 좋은 패턴이 있습니까?ASP.NET MVC 경쟁 조건? Factory Singleton Static Dictionary

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 

답변

1

귀하의 코드는 거의 것과 동일 C#에서 싱글 톤 구현을 논의 MSDN article에 샘플 코드. 그 기사는 꽤 좋다. 나는 그것을 추천한다.

. (을)를 사용하여 critical 섹션을 구현하기 위해 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; 
     } 
    } 
} 

이 코드를 컴파일하지 않았고 스트레스 테스트를 많이 수행하지 않았습니다. 당신이 그것을 시도한다면,이 작품이 있으면 알려주십시오!

+0

사실 저는이 일이 다시 일어나지 않도록 전역 init에서 Instance 메서드를 호출하기로 결정했습니다. –

+0

최신 버전의 .NET에서이를 구현하는 몇 가지 방법이 있습니다. 나는 요즘 사용되는 double null check + locking 기술을 거의 보지 못합니다. 대부분의 사람들은'Lazy ' 래퍼를 사용합니다. –