2009-12-30 3 views
2

자체 호스팅 WCF 서비스가 있는데 다음과 같은 문제가 있습니다. 서비스 계약 인스턴스의 TryEnter 호출을 생성 한 후 15 분이 계속 false를 반환하지만 TryEnter Monitor 클래스를 통한 동기화를 사용하는 Main 함수의 호출은 true를 반환합니다.WCF 서비스의 Monitor 클래스 동기화 문제

다음은 내 앱 및 버그에 대한 설명입니다. Windows XP SP2의 Visual Studio 2008 (C#)에서 자체 호스팅 WCF 서비스를 개발 중입니다. 호스트의 ServiceHost 인스턴스는 Main 함수의 시작 부분에 만들어집니다. Main 함수는 정기적 인 읽기, 쓰기, 유지 관리 등을 수행하는 while (true) 루프를 실행합니다. 작업자 스레드의 컨테이너 역할을하는 정적 컬렉션 개체 (시간이 지남에 따라 추가 또는 제거 할 수 있음)가 있습니다. 이 스레드 중 일부는 Main 함수가 요청한 정기 작업을 수행하는 반면, 다른 일부는 원격 장치에 주문형 읽기 및 쓰기를 수행합니다. 동기화 잠금은 Monitor 클래스 (TryEnter 및 Exit 메소드)를 사용하여 이러한 객체에 대해 수행됩니다. 이러한 객체는 동일한 기능을 사용하는 서비스 계약 메소드 (서비스)를 통해 액세스 할 수도 있습니다. 동기화는 Main 함수와 서비스 메소드 사이에서 수행됩니다. 서비스의 인스턴스가 생성되면 정확히 15 분 동안 설계된 성능으로 실행되고, 그 후에 지정된 시간 초과가 만료 된 후 서비스에서 작성된 모든 TryEnter (obj, timeout) 호출이 false를 반환합니다. 그러나 이것은 Main 함수에서 호출 된 TryEnter 호출에 영향을주지 않습니다. 즉, 항상 true를 반환합니다. 서비스 제한 특성과 결합 된 InstanceContextMode, ConcurrencyMode에 대한 설정을 변경하려고 시도했습니다. maxConcurrentCalls = "1"; maxConcurrentSessions = "5" 및 모든 구성이 동일한 효과를 나타냅니다. 호스트 응용 프로그램을 다시 시작할 때 서비스가 다시 응답하지만 응용 프로그램이 실행 중일 때 호스트를 강제로 닫았다가 다시 열 때 (서비스 인스턴스가 메모리에 남아 있음)가 아닙니다. 전화가 서비스 인스턴스로 연결되지 않는 경우와 같이 서비스를 사용할 수없는 경우는 아닙니다. 메서드가 호출되면 메서드의 중요 섹션 앞에 오는 TryEnter 호출이 실행되고 TryEnter는 제한 시간 (15 초) 후에 false를 반환합니다. TryEnter와 Exit의 쌍을 확인하고 이중 체크했다. 중요한 섹션이 끝나면 메소드는 항상 잠금을 해제한다. 잠금을 사용하지 않는 기타 계약 작업 또는 문제의 오브젝트는 15 분의 기간이 끝난 후에도 잘 작동합니다.

감사합니다. 행복한 명절!

답변

3

Monitor은 재진입이므로 Main 메서드가있는 스레드가 잠금을 해제하지 못한 것 같습니다. 그래서 자물쇠 (TryEnter)를 요청하면 자물쇠가 생깁니다 (카운터를 또 하나로 증분).

다른 모든 스레드는 거부됩니다. 잠금이 걸리고 유지되는 곳을 디버깅해야합니다.

내가 확인하고 더블 TryEnter 및 종료의 짝을 점검 한 - 중요한 부분은

죄송 끝날 때 방법은 항상 잠금을 해제,하지만 난 당신이 고음 검사를하는 것 같아요. 특히 lock과 달리 TryEnter에는 특별한 예외 처리가 없습니다. 또한

if(Monitor.TryEnter(lockObj, timeout)) { 
    try { 
     ... 
    } finally { 
     Monitor.Exit(lockObj); 
    } 
} 

- 올바른 개체의 잠금을 해제하지 않을 것이다 결코 코드에 lockObj reasign,이 같은 있는지 확인하십시오 귀하의 코드처럼 보일 것입니다.

(또는 특히 .NET 4.0에서 플래그를 사용하는 경우 there are new overloads의 경우 Enter 등)