2014-10-07 3 views
2

나는이 튜토리얼을 따라 Windows 서비스를 만들 수있다 : http://msdn.microsoft.com/en-us/library/zt39148a(v=vs.110).aspx. Quartz.Net을 사용하여 많은 작업을 관리하는 TaskManager 클래스가 있습니다. 그것에는 .Go() (차단하지 않음)과 .Stop() 방법이 있습니다. 내가 올바르게 이해했다면, 내 봉사에서해야 할 일은 모두serviceStatus.dwWaitHint의 값을 선택하는 방법은 무엇입니까?

private TaskManager _taskManager; 

    public DataPumpService() 
    { 
     InitializeComponent(); 
     _taskManager = new TaskManager(); 
    } 

    protected override void OnStart(string[] args) 
    { 
     _taskManager.Go(); 
    } 

    protected override void OnStop() 
    { 
     _taskManager.Stop(); 
    } 

입니다.하지만이 튜토리얼에는 서비스 상태를 설정하는 절이 있습니다. 실제로 서비스 상태가 무엇인지 또는 내가 설정하려고하는지는 설명하지 않습니다. TaskManager.Stop()을 완료하는 데 몇 초가 걸릴 수 있습니다 (내부적으로 모든 작업에서 IScheduler.Interrupt()을 호출 한 다음 IScheduler.Shutdown(true)이라고 부름). 그럼 상태를 설정해야합니까? 그렇다면 설정 서비스 상태 섹션 the tutorial의 섹션 (1), (2) 및 (3)에 코드를 포함한다고 가정하면 위의 첫 번째 코드 블록에서 두 가지 방법 모두에 대해 다음을 수행하는 것이 올바른지 여부입니다. 이 옳다면, 나는 현명하게 선택해야하거나 기본값을 고수하는 좋은 일이다 serviceStatus.dwWaitHint = 100000; 속성 뭔가

protected override void OnStop() 
    { 
     // Update the service state to Stop Pending. 
     ServiceStatus serviceStatus = new ServiceStatus(); 
     serviceStatus.dwCurrentState = ServiceState.SERVICE_STOP_PENDING; 
     serviceStatus.dwWaitHint = 100000; 
     SetServiceStatus(this.ServiceHandle, ref serviceStatus); 

     _taskManager.Stop(); 

     // Update the service state to Running. 
     serviceStatus.dwCurrentState = ServiceState.SERVICE_STOPPED; 
     SetServiceStatus(this.ServiceHandle, ref serviceStatus); 
    } 

입니까? 기본적으로 나는이 값이 @HansPassant으로

+1

흠, 어떻게 MSDN 문서에 포함 시켰는지 확실하지 않습니다. ServiceBase 클래스가 이미 서비스 상태를 처리하는 방식은 99.9 %의 경우에 충분합니다. 이 dwWaitHint를 포함하여 ServiceBase.RequestAdditionalTime() 메소드로 래핑됩니다. 당신은 그것을 필요로하지 않아야한다. 30 초는 모든 서비스 시작의 99.9 %를 얻는 데 충분하다. :) 4.5 이전에이 기사의 어떤 버전도 그것에 대해 이야기하지 않는다. –

+0

@HansPassant 그래서 첫 번째 코드 블록을 사용하고 serviceStatus를 전혀 사용하지 않으면 일반적으로 괜찮습니까? 또한 30 초까지는 무엇을 의미합니까? 기본 값입니까, 아니면 100000 대신 30000을 사용 하시겠습니까? – Dan

+2

혼란스럽지 마라. Windows에서 사용하는 기본 시간 제한은 30 초입니다. –

답변

2

ServiceBase 클래스는 이미 서비스 상태 을 담당하는 방식이 사례의 99.9 %에 충분 말한다위한 ... 무엇인지 전혀 모른다. 30 초 (기본값)는 모든 서비스 의 99.9 %를 시작/중지 할만큼 충분합니다.

dwWaitHint

보류중인 시작에 필요한 예상 시간에 관한

당신이 장기 실행 가까이를 처리해야하는 경우 단, documentation 말한다는 일시 중지 또는 계속 작업 (밀리 초 단위). 지정된 시간이 경과하기 전에 서비스는 의 다음 호출을 사용하여 SetServiceStatus 함수에 증가 된 dwCheckPoint 값 또는 dwCurrentState의 변경 사항을 지정해야합니다. dwWaitHint에 의해 이 지정되고 dwCheckPoint가 증가하지 않았거나 dwCurrentState가 변경되지 않은 경우 서비스 제어 관리자 또는 서비스 제어 프로그램은 오류가 발생했으며 서비스 을 중지해야한다고 간주 할 수 있습니다. 그러나 서비스가 다른 서비스와 프로세스를 공유하는 경우 서비스 제어 관리자는 다른 서비스도 종료해야하므로 서비스를 종료 할 수 없습니다. 프로세스도 공유합니다.

dwCheckPoint는

서비스 단위로 주기적으로 긴 시작할 때 진행 상황을보고 할 수있는 체크 포인트 값, 일시 중지, 중지 또는 는 작업을 계속합니다.예를 들어 서비스는 이 시작될 때 초기화의 각 단계를 완료 할 때이 값을 증가시켜야합니다. 에서 작업을 호출 한 사용자 인터페이스 프로그램은이 값을 사용하여 오랜 작업 중에 서비스의 진행 상태를 추적합니다. 이 값은 유효하지 않으므로 서비스에 시작, 중지, 일시 중지 또는 계속 진행 중이 아닌 경우 작업이 보류 중일 때 0이어야합니다.

이렇게하면 walk-through의 각주가 명확 해집니다. Windows 서비스를 시작하거나 종료하는

는 서비스 제어 관리자는 대기에 얼마나 많은 시간을 결정하기 위해 SERVICE_STATUS 구조의 dwWaitHint 및 dwCheckpoint 멤버를 사용합니다. OnStart 및 OnStop 메서드가 길게 실행되는 경우 서비스는 SetServiceStatus를 증가 된 dwCheckPoint 값으로 다시 호출하여 더 많은 시간을 요청할 수 있습니다.

이에 기초하여 제 스톱 코드를 작성했습니다. 몇 가지 매우 긴 작업을 실행하고 종료하는 것은 좋은 생각이 아니므로 대기 시간이 길다는 점에 유의하십시오.

//set the status to pending close 
var serviceStatus = new ServiceStatus 
{ 
    dwCurrentState = ServiceState.SERVICE_STOP_PENDING, 
    dwWaitHint = 120000//two minutes wait time 
}; 
SetServiceStatus(this.ServiceHandle, ref serviceStatus); 

Engine.Cancel(); 

while (Engine.IsRunning()) 
{ 
    System.Threading.Thread.Sleep(1000); 
    serviceStatus.dwCheckPoint++;//updating the checkpoint so I don't get terminated 
    SetServiceStatus(this.ServiceHandle, ref serviceStatus); 
} 
+0

감사합니다.이 답변의 맨 위에 Hans Passant가 댓글에서 말한 부분, 즉 기본값을 그대로 사용해야하는 경우의 99.9 %를 지정하는 섹션을 추가하면 기꺼이이를 수락합니다. – Dan

+0

추가했습니다. 감사. 실제로 더 나은 방법입니다. – frostymarvelous

관련 문제