2010-02-15 5 views
1

내 Windows 서비스는 상당한 캐시가있는 데이터 서버입니다. OnStop 서비스 중에 데이터를 잃어 버리지 않도록 캐시를 저장합니다. 잘 작동시스템 종료 중에 .NET Windows 서비스가 중단되었습니다.

this.serviceStatus.currentState = (int)State.SERVICE_STOP_PENDING; 
this.serviceStatus.checkPoint = 1; 
this.serviceStatus.waitHint = 60000; 
SetServiceStatus(Process.GetCurrentProcess().Handle, ref this.serviceStatus); 

: 캐시를 저장하는 타임 아웃에서 Windows 서비스 관리자를 방지하기 위해 그렇게 몇 분 정도 걸릴 수 있습니다 나는 SetServiceStatus에서 Win32 콜백을 사용합니다.

또한 CanShutdown을 true로 설정하고 OnShutdown을 추가하여 서비스가 시스템 종료 증명이되도록합니다. 여기서 나는 효과적으로 OnStop에서와 같은 일을합니다 :

protected override void OnShutdown() 
{ 
    this.OnStop(); 
    base.OnShutdown(); 
} 

그다지 좋지 않습니다. 시스템이 종료되면 캐시가 저장 될 때 "장치가 준비되지 않았습니다"라는 메시지가 나타납니다. 이것은 Windows가 중지/종료를 완료하기 전에 서비스를 중단한다는 것을 의미합니다. SetServiceStatus를 사용하면이를 방지 할 수 없습니다.

절약을 완료하려면 어떻게 시간이 오래 걸리며 재부팅을 지연합니까?

모든 의견을 환영합니다.

+0

빠른 질문 - 일분 - waitHint은 60 초입니다. 그게 정말로 필요한거야? (당신은 몇 분이 필요하다고 말했습니다). –

+2

난 그냥 여기에 손을 들고 왜 이런 식으로 행동 오래 캐시를 구현하는 질문을 제기하는 사람이 있어야합니다. 당신의 모든 디자인이 무효하다는 말은 아니에요. 그리고 그것은 프랑스의 아주 훌륭한 치즈 일 수도 있고, 아주 나쁜 것일 수도 있습니다. –

+0

네 손을 들었어, 데이브. 나는 당신의 마음에 무엇이 있는지 알고 있습니다. 서비스가 그 양의 데이터를 메모리에 보관하지 않도록하십시오. 그러나 그것은 캐시의 아이디어입니다. 캐시는 여러 상황에서 저장되지만 시스템 종료 직전에 데이터로로드 될 수 있습니다. 그리고 서버는 거의 재부팅되지 않습니다. 그러나 나는 최악의 상황에 대비해야한다. –

답변

0

일부 테스트를 마친 후에는 내 서비스가 아닌 시스템에 문제가있는 것 같습니다.

0

ManualResetEvent을 사용하는 것이 트릭 일 수 있습니다.

+0

ManualResetEvent가 여기에 어떤 이점이 있는지 나는 알지 못합니다. 서비스 종료를 요청하는 스레드를 제어 할 수 없어 어쨌든 동기화를 원하지 않습니다. OnShutdown이 끝나기 전에 Windows가 내 서비스를 종료하지 못하도록하려는 것입니다. OnStop에 SetServiceStatus와 같은 기능이 있습니다. –

+0

ManualResetEvent는 기본적으로 스레드를 대기시키는 방법을 제공하므로 도움이 될 것이라고 생각했습니다. 귀하의 요점을 볼 수 있습니다 - 다른 프로세스가 귀하의 서비스를 종료 할 때를 감지 할 수 없다면[email protected] marc.d와 마찬가지로이 캐시를 더 자주 저장하는 것이 좋습니다. 그는 아주 유효한 점을 가지고 있습니다. – IAbstract

+0

극한의 시스템입니다. 캐시를 더 자주 저장하지만 너무 많은 데이터가있을 수 있습니다. 쓰기 캐시입니다. 데이터를 저장하는 것보다 훨씬 빨리 데이터를 전송할 수 있으며 지속적인 스트림입니다. 트릭은 캐시가 데이터를 수평에서 수직으로 재 배열하므로 데이터를 저장하는 것이 훨씬 효율적이므로 데이터를 저장하기 전에 일부 데이터를 누적해야한다는 것입니다. 시스템 종료가 발생할 때 데이터가 전혀 없거나 많은 데이터가있을 수 있습니다. –

2

이 문제를 처리하는 가장 좋은 방법은 this article on the BCL Team's blog입니다. 이 기사에는 관리 서비스가 SCM과 상호 작용하는 방식에 대한 약간의 배경 지식이 포함되어 있는데, 이는 질문에 표시된 접근 방식이 더 이상 권장되지 않는 이유를 이해하는 데 중요합니다.

간단히 말해서 ServiceBase가 서비스 상태 관리를 처리하고 코드가 필요한 경우 추가 시간을 요청하면됩니다. .NET에서 SCM 친화적 인 서비스를 작성하기위한 몇 가지 다른 좋은 지침을 보려면이 기사를 읽으십시오.

+0

정답은 아니지만 유용합니다. 나는 서비스 컨트롤러로부터 더 많은 시간을 요청하는 선호 된 방법을 찾고 있지 않았다. (하지만 지금부터 그렇게 할 것이다.) 그 블로그의 마지막 부분에서 나는 왜 shutdown이 stop 이벤트와 다른지에 대한 정보를 발견했습니다. –

0

또 다른 쉬운 방법은 setservicestatus 방법을 포함하는 방법에 대한 검색 시간 후 :

protected override void OnStop() 
    { 
     stopTimer(); 
     m_run = false; 
     while (m_queue.Count > 0) 
      Thread.Sleep(500); 
    } 
+0

내가 내 질문에 언급했듯이이 서비스는 중지 중에 작동하지만 서비스가 지정된 시간 내에 OnStop에서 돌아 오지 않을 때 (시스템 별) 중단되기 때문에 종료 중에는 작동하지 않습니다. –

관련 문제