문제

Windows 서비스에서 UnhandledException 처리기를 사용할 수 있습니까?

일반적으로 나는 로깅, 전화 집 등을 수행하는 맞춤형 예외 처리 구성 요소를 사용합니다.이 구성 요소는 System.AppDomain.CurrentDomain.UnhandledException에 처리기를 추가하지만 내가 알 수 있는 한 이것이 Windows 서비스에서 아무 것도 달성하지 못하므로 2(또는 4) 서비스 진입점에서 다음 패턴으로 끝납니다.


    Protected Overrides Sub OnStart(ByVal args() As String)
        ' Add code here to start your service. This method should set things
        ' in motion so your service can do its work.
        Try
            MyServiceComponent.Start()
        Catch ex As Exception
            'call into our exception handler
            MyExceptionHandlingComponent.ManuallyHandleException (ex)
            'zero is the default ExitCode for a successfull exit, so if we set it to non-zero
            ExitCode = -1
            'So, we use Environment.Exit, it seems to be the most appropriate thing to use
            'we pass an exit code here as well, just in case.
            System.Environment.Exit(-1)
        End Try
    End Sub

OnStart를 지저분한 예외 처리 배관으로 채울 필요가 없도록 사용자 정의 예외 처리 구성 요소가 이를 더 잘 처리할 수 있는 방법이 있습니까?

도움이 되었습니까?

해결책

좋아, 지금은 이것에 대해 좀 더 조사해 봤습니다..Net에서 Windows 서비스를 만들 때 System.ServiceProcess.ServiceBase에서 상속되는 클래스를 만듭니다(VB에서는 .Designer.vb 파일에 숨겨져 있음).그런 다음 OnStart 및 OnStop 함수를 재정의하고 원하는 경우 OnPause 및 OnContinue를 재정의합니다.이러한 메서드는 기본 클래스 내에서 호출되므로 리플렉터를 조금 살펴보았습니다.OnStart는 ServiceQueuedMainCallback이라는 System.ServiceProcess.ServiceBase의 메서드에 의해 호출됩니다.내 컴퓨터 "System.ServiceProcess, Version=2.0.0.0"의 버전은 다음과 같이 디컴파일됩니다.


Private Sub ServiceQueuedMainCallback(ByVal state As Object)
    Dim args As String() = DirectCast(state, String())
    Try 
        Me.OnStart(args)
        Me.WriteEventLogEntry(Res.GetString("StartSuccessful"))
        Me.status.checkPoint = 0
        Me.status.waitHint = 0
        Me.status.currentState = 4
    Catch exception As Exception
        Me.WriteEventLogEntry(Res.GetString("StartFailed", New Object() { exception.ToString }), EventLogEntryType.Error)
        Me.status.currentState = 1
    Catch obj1 As Object
        Me.WriteEventLogEntry(Res.GetString("StartFailed", New Object() { String.Empty }), EventLogEntryType.Error)
        Me.status.currentState = 1
    End Try
    Me.startCompletedSignal.Set
End Sub

따라서 Me.OnStart(args)가 Try Catch 블록의 Try 부분 내에서 호출되기 때문에 OnStart 메서드 내에서 발생하는 모든 작업은 해당 Try Catch 블록에 의해 효과적으로 래핑되므로 발생하는 모든 예외는 다음과 같이 기술적으로 처리되지 않습니다. 실제로는 ServiceQueuedMainCallback Try Catch에서 처리됩니다.따라서 CurrentDomain.UnhandledException은 적어도 시작 루틴 중에 실제로 발생하지 않습니다.다른 3개의 진입점(OnStop, OnPause 및 OnContinue)은 모두 비슷한 방식으로 기본 클래스에서 호출됩니다.

그래서 내 예외 처리 구성 요소가 시작 및 중지 시 UnhandledException을 포착할 수 없는 이유를 설명하는 것으로 '생각'하지만 OnStart에 설정된 타이머가 실행될 때 UnhandledException을 발생시킬 수 없는 이유를 설명하는지 잘 모르겠습니다.

다른 팁

다음을 구독할 수 있습니다. AppDomain.UnhandledException 이벤트.메시지 루프가 있는 경우 다음과 같이 연결할 수 있습니다. Application.ThreadException 이벤트.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top