2010-02-02 2 views
2

싱글 톤을 통해 액세스 할 공유 개체를 사용하여 응용 프로그램에서 작업하고 있습니다. 32 비트에서는 잘 작동하지만 64 비트에서는 제대로 잠그지 않는 것 같습니다. 내 개체에 대한 생성자에서 몇 가지 구성 reg 키를 확인하고 존재하지 않는 경우 사용자에게 묻는 코드가 있습니다. 32 비트에서 나는 프롬프트가 한 번만 예상되는 것처럼 보이지만 64 비트에서는 프롬프트가 여러 번 표시됩니다. 내 코드는 다음과 같습니다.싱글 톤 구현 작동 32 비트 있지만 64 비트 않습니다.

private static readonly object padlock = new object(); 
    private static MyClass _instance = null; 
    public static MyClass Instance 
    { 
     get 
     { 

      lock (padlock) 
      { 
       if (_instance == null) 
       { 
        _instance = new MyClass(); 
       } 
      } 
      return _instance; 
     } 
    } 

모든 입력 사항에 크게 감사드립니다. 다시

public OtherObject() 
    { 
     InitializeComponent(); 

     MyClass.Instance.OtherObjectOrSomething = this; 

     this.Load += new System.EventHandler<EventArgs>(OtherObject_Load); 
    } 

편집을이 사무실 추가 기능의 내부 실행 :

샘플 사용을 포함하는을 편집. 따라서 비트는 사무실 설치에 의해 결정됩니다. private 인 매개 변수없는 생성자를 정의합니다.

감사

제거 약간 Anonimized 생성자

+0

매개 변수없는 생성자가 '비공개'로 표시 되었습니까? 싱글 톤의 인스턴스를 사용하기 위해 사용중인 코드 스 니펫을 표시하십시오. – jason

+0

게시물에 스 니펫을 추가했습니다. 공정한 양의 다른 장소에서이 객체에 액세스하지만 각 인스턴스마다 액세스를 위해 MyObject.Instance를 사용하고 있습니다. –

+0

이 작업은 VS 내에서만 발생합니까? Monitor oddities와 관련된 첫 번째 작업은 해당 클래스 (인스턴스)에 대한 모든 참조를 조사 및 디버그 창에서 제거하는 것입니다. VS는 때때로 자신의 방식대로 일을하고 싶어하며 잠금 장치도 우회합니다. ... – MaLio

답변

0

편집 : 몇 가지 답변과 의견에 따라 , 내 원래의 대답으로 돌아갈 것입니다.

읽기 전용을 휘발성으로 변경하는 것을 제외하고 나는 그렇게했습니다.

휘발성 키워드를 사용하면 컴파일러는 명령을 최적화하지 말고 가장 최신 값이 필드에 있는지 확인할 수 있습니다.

+0

나는 무례하기를 의미하지는 않으므로 그렇게하지 마십시오. 그러나 이것은 질문에 대답하는 데 도움이되지 않습니다. OP의 싱글 톤 구현은 허용 가능합니다. 올바른, 스레드 안전하고 간단합니다 (매개 변수없는 생성자가'private'으로 표시되어있는 한). 인스턴스가 요청 될 때마다 '잠금'이 취해지기 때문에 성능이 저하됩니다. '휘발성 '을 추가하는 것은 아무런 도움이되지 않습니다. 문제가 무엇인지 이해하는 데 집중하십시오. – jason

+0

@ Jason 휘발성으로 인해 문제가 해결 될 것이라는 말은하지 않았으므로이를 제거 하겠지만, 링크 된 게시물은 특정 멀티 프로세서 시스템에서 위의 방법이 실패했다는 잘못된 설명입니다. ? –

+0

블로그에는 중요한 차이점이 있습니다. 자물쇠는 그 물건의 요점 인 if 주위에 간다. lock 이전에 문제가있는 경우, 다른 스레드가 syncRoot를 잠그기 전에 동시에 여러 스레드가 if에 충돌 할 수 있습니다. –

0

다양한 싱글 톤 구현 패턴과 관련된 문제에 대한 자세한 내용은 http://www.yoda.arachsys.com/csharp/singleton.html (Jon Skeet 출간)을 참조하십시오.

작성된 것처럼 가장 큰 문제는 컴파일러가 공개 될 기본 매개 변수없는 생성자를 제공한다는 것입니다. 이것을 방지하기 위해 비공개 인 paramaterless contstructor를 명시 적으로 만들어야합니다. 플랫폼 아키텍처를 기반으로하는 문제를 일으키는 것처럼 보이는 것은 보이지 않습니다.

public sealed class Singleton 
{ 
    private static volatile Singleton instance; 
    private static object syncRoot = new object(); 

    private Singleton() 
    { 
     // any code that needs to run to create a valid instance of the object. 
    } 

    public static Singleton Instance 
    { 
     get 
     { 
     if (instance == null) 
     { 
      lock(syncRoot) 
      { 
       if (instance == null) 
       { 
        instance = new Singleton(); 
       } 
      } 
     } 

     return instance; 
     } 
    } 
} 
+0

죄송 합니다만, 위의 David Glass에게 준 동일한 의견 (http://stackoverflow.com/questions/2187090/singleton-implementation-works-fine-on-32-bit-but-not-64-bit)/2187188 # 2187188) :이 질문에 대답하는 데 도움이되지 않습니다. – jason

+0

@ Jason : 내 업데이트를 확인하십시오. 나는 보이는 문제의 근원이 완전히 정확하지 않은 구현이라고 생각한다. 아키텍처 (32 비트 또는 64 비트)는 스레드 잠금이 작동하는 방식에 아무런 영향을 미치지 않아야하지만, 단일 스레드에서 잠금 코드가 절대적으로 구현되는 방식은 다릅니다. 개인 인스턴스 변수를 '휘발성'으로 구현하면 메모리 액세스에 영향을 미칩니다. –

+0

@ Scott Dorman : 그렇습니다. 우리가 보여주지 않은 코드의 일부에서 잘못 구현 될 가능성이 매우 높습니다. – jason

2

그것은 여러 프롬프트를 일으키는 원인이되는 생성자의 코드 내부에 뭔가가 될 수 있습니다 : 여기

은 (32 비트 및 64 비트 시스템에서) 내가 일반적으로 사용하는 코드입니다. 레지스트리보기는 32 비트 프로세스 대 64 비트 프로세스와 다를 수 있으므로 다른 외부 조건에 응답 할 수 있습니다.

0

here 구현을 함께 사용했지만 몇 가지 이유 때문에 두 번 downvoted되었습니다 :(

0

귀하의 싱글은 응용 프로그램 도메인 당 하나 개의 인스턴스를 제한합니다. 배수 여러 응용 프로그램 도메인에서 만들어지고 어떤 기회? 당신은으로 보일 수 있습니다. 내 객체의 생성자에서

0

을 내가 코드를 일부 설정 등록 키를 확인하고 은 사용자에게 존재하지 않는지 묻는 메시지를 표시합니다.

지연로드 정적 인스턴스에서 수행하는 것이 다소 위험한 작업입니다. UI 스레드가 항상이 코드 경로를 실행하는 첫 번째 스레드임을 보장 할 수 있습니까? 이것이 당신의 문제의 일부인지는 모르겠지만, thread-safe 코드 안에서 UI와 상호 작용하는 것은 거의 좋은 생각이 아니며, 결과적으로 다양한 환경에서 모든 종류의 이상한 일들이 일어나는 것을 보았습니다.

이 UI 코드를 느린로드 외부로 옮길 수 있습니까? 이것이 Office Add-In 인 경우 후크하려면 Startup 이벤트가 있어야하며 이는 한 번만 실행되도록 보장됩니다. 그런 식으로 잠금 코드가 필요하지 않습니다. 다른 스레드가 잠금 코드를 만지기 전에 초기화되도록 할 수 있습니다.