2008-09-12 23 views
24

Có thể sử dụng Trình xử lý UnhandledException trong Dịch vụ Windows không?Trình xử lý ngoại lệ UnhandledException trong Dịch vụ Windows .NET

Thông thường tôi sẽ sử dụng Thành phần xử lý ngoại lệ được xây dựng tùy chỉnh để ghi nhật ký, nhà điện thoại, v.v. Thành phần này thêm trình xử lý vào System.AppDomain.CurrentDomain.UnhandledException nhưng theo như tôi có thể nói điều này không đạt được bất kỳ điều gì một Dịch vụ Windows để tôi kết thúc với mẫu này trong các điểm nhập của Dịch vụ 2 (hoặc 4) của tôi:

 

    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 
 

Có cách nào mà thành phần Xử lý ngoại lệ tùy chỉnh của tôi có thể giải quyết tốt hơn để tôi không phải điền OnStart của tôi với hệ thống ống nước xử lý ngoại lệ lộn xộn?

Trả lời

15

Ok, tôi đã nghiên cứu thêm một chút về vấn đề này ngay bây giờ. Khi bạn tạo một dịch vụ cửa sổ trong .Net, bạn tạo một lớp kế thừa từ System.ServiceProcess.ServiceBase (Trong VB này được ẩn trong tệp .Designer.vb). Bạn sau đó ghi đè lên các OnStart và OnStop chức năng, và OnPause và OnContinue nếu bạn chọn. Những phương pháp này được gọi từ bên trong lớp cơ sở vì vậy tôi đã làm một chút poking xung quanh với phản xạ. OnStart được gọi bằng một phương thức trong System.ServiceProcess.ServiceBase được gọi là ServiceQueuedMainCallback. Các vesion trên máy tính của tôi "System.ServiceProcess, Version = 2.0.0.0" dịch ngược như thế này:

 

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 
 

Vì vậy, vì Me.OnStart (args) được gọi từ bên trong phần Thử của một khối Try Catch tôi cho rằng bất cứ điều gì xảy ra trong phương thức OnStart đều được bao bọc bởi khối try catch đó và do đó bất kỳ ngoại lệ nào xảy ra không được giải quyết về mặt kỹ thuật vì chúng thực sự được xử lý trong ServiceQueuedMainCallback Try Catch. Vì vậy, CurrentDomain.UnhandledException không bao giờ thực sự xảy ra ít nhất trong suốt quá trình khởi động. 3 điểm vào khác (OnStop, OnPause và OnContinue) đều được gọi từ lớp cơ sở theo cách tương tự. Vì vậy, tôi nghĩ rằng 'giải thích tại sao thành phần xử lý ngoại lệ của tôi không thể bắt UnhandledException trên Start và Stop, nhưng tôi không chắc liệu nó giải thích tại sao bộ hẹn giờ được thiết lập trong OnStart không thể gây ra một UnhandledException khi chúng ngọn lửa.

+3

Tôi thấy rằng sự kiện UnhandledException trong một dịch vụ không nhận được ngoại lệ trong các chủ đề khác, miễn là bạn kết nối bộ xử lý sự kiện rất sớm. Tôi đã kết nối nó trong constructor dịch vụ thay vì phương thức OnStart(). Điều này cũng loại bỏ hệ thống ống nước ngoại lệ xấu xí khỏi OnStart() của bạn. – saille

2

Bạn có thể đăng ký AppDomain.UnhandledException event. Nếu bạn có vòng lặp tin nhắn, bạn có thể liên kết với số Application.ThreadException event.

+0

phản hồi của tôi với bạn đã bị xóa (một vài năm trước) Tôi nghĩ tôi sẽ đưa nó trở lại như một bình luận, đó là những gì nó nên có được tất cả cùng: Cảm ơn câu trả lời Garo nhưng như tôi đã nói trong câu hỏi ban đầu của tôi , Trình xử lý ngoại lệ của chúng ta thêm một trình xử lý vào System.AppDomain.CurrentDomain.UnhandledException nó đơn giản không hoạt động khi sử dụng nó trong ngữ cảnh của một Dịch vụ Windows. – Scott

Các vấn đề liên quan