2011-01-05 5 views
2

Server A에서 Server B으로 문서를 이동시키는 SSIS 패키지를 주기적으로 실행하는 Windows 서비스를 작성했습니다.OnStart() 메서드에서 무한 루프로 인해 Windows 서비스가 항상 "시작"중임

문제는 서비스를 시작할 때 시작되는 무한 루프를 사용해야한다는 것입니다.

당연히이 루프를 OnStart() 메서드에 넣었습니다.

protected override void OnStart(string[] args) 
{ 
    Application app = new Application(); 
    Package pkg = app.LoadFromDtsServer(@"MSDB\PullDoc", "Server", null); 
    while (true) 
    { 
     DTSExecResult pkgResults = pkg.Execute();//Execute the package. 
     EventLog.WriteEntry(pkgResults.ToString()); 
     Thread.Sleep(1000 * 60 * 5);//Sleep at least five minutes. 
    } 
} 

내가이 일반적인 문제입니다 상상, 주어진 : 불행하게도, 서비스는이 방법의 끝에 도달하지 이후 여기

는 관련 코드 ... 시작되었음을 신호를 결코 대부분의 서비스가 무기한으로 실행되어야합니다.

이 서비스가 시작된 것을 반환하는 방법에 대한 아이디어가 있으십니까?

감사합니다.

답변

4

무한 루프 대신 System.Threading.Timer을 사용해야합니다.

+0

관련 질문 : 타이머를 사용할 때 메서드가 아직 실행을 완료하지 않은 경우에도 5 분마다 콜백 메서드가 호출됩니다. 방법의 끝까지 계산하지 않는 간단한 방법이 있습니까? – nosirrahcd

+0

@user : 타이머가 한 번만 실행되도록 설정 한 다음 메서드가 끝날 때 다시 시작합니다. – SLaks

3

서비스가 다른 스레드에서 작동해야합니다. OnStart, OnStop 등의 메서드는 Windows 서비스 제어 관리자 (SCM)에서 사용자의 서비스에 대한 명령을 처리하기위한 것이며 SCM은 해당 서비스가 즉시 반환 될 것으로 기대합니다.

@SLaks에서 제안한대로 System.Threading.Timer을 사용하면 타이머 이벤트가 .NET 스레드 풀의 스레드에서 실행됩니다. OnStart 메서드는 Timer를 활성화하고 OnStop 메서드는 타이머를 비활성화합니다 (OnPause 및 OnResume은 원할 경우 마찬가지로 수행 할 수 있음).

2

이 작업을 제대로 수행하지 않으면 함수가 반환되지 않도록해야하며 새 스레드를 사용해야합니다. 제안 된대로 Timer 개체를 사용해야합니다. 여기에 방법을 보여주는 코드입니다 :

private void OnElapsedTime(object source, ElapsedEventArgs e) 
    { 
     CopyAToB(); 
    } 
    Timer timer = new Timer(); 
    protected override void OnStart(string[] args) 
    { 
     timer.Elapsed += new ElapsedEventHandler(OnElapsedTime); 
     timer.Interval = 60000 * 5; 
     timer.Enabled = true; 
    } 
    private void CopyAToB() 
    { 
     // do somethings 
    } 
+0

Windows 서비스에서 System.Timers.Timer 또는 System.Threading.Timer를 사용하려고합니다. 자세한 내용은이 게시물을 참조하십시오. http://stackoverflow.com/questions/246697/windows-service-and-timer – Zman101

1

난 당신이 제안 같은이 System.Threading.Timer를 사용하는 것이 좋습니다 것이지만, 여기에 내가 기능을 구현하는 방법의 예입니다.

이 예제에서는 한 시간에 4 번 실행되는 함수가 있으며 이전 호출에서 여전히 실행 중인지 신속하게 확인하고 그렇지 않은 경우 건너 뛸 경우 새 스레드가 만들어지고 함수가 실행되지 않습니다.

Imports System.Threading 

Public Class myService 

    Private myThreadingTimer As System.Threading.Timer 
    Private keepRunning As Boolean = False 
    Private processing As Boolean = False 

    Protected Overrides Sub OnStart(ByVal args() As String) 
    Dim myTimerCallback As New TimerCallback(AddressOf OnTimedEvent) 

    If YourCheckHere() Then 
     keepRunning = True 
     myThreadingTimer = New System.Threading.Timer(myTimerCallback, Nothing, 1000, 1000) 
    Else 
     'What you want to do here 
    End If 
    End Sub 

    Protected Overrides Sub OnStop() 
    keepRunning = False 
    End Sub 

    Private Sub OnTimedEvent(ByVal state As Object) 
    If Date.Now.Minute = 14 And Date.Now.Second = 31 Or Date.Now.Minute = 29 And Date.Now.Second = 31 _ 
    Or Date.Now.Minute = 44 And Date.Now.Second = 31 Or Date.Now.Minute = 59 And Date.Now.Second = 31 _ 
    Then 
     'Make Sure Its Supposed To Still Be Running 
     If keepRunning Then 
     'Make Sure The Process Is Not Already Running 
     If Not processing Then 
      'Process is not currently running lets start it 
      Dim myThread As New Thread(New ThreadStart(AddressOf myProcess)) 
      myThread.Start() 
     End If 
     End If 
    End If 
    End Sub 

    Public Sub myProcess() 
    Try 
     ' Set the processing flag so the function does not run again until complete 
     processing = True 

     'Do whatever logic you need here 

    Catch ex As Exception 
     'Since You Can Not Use A MessageBox Do Logging Or Whatever You Need Here 

    Finally 
     processing = False 
    End Try 
    End Sub 

End Class 
관련 문제