سؤال

هل من الممكن استخدام معالج UnhandledException في خدمة Windows؟

عادةً ما أستخدم مكون معالجة الاستثناءات المصمم خصيصًا والذي يقوم بالتسجيل والهاتف المنزلي وما إلى ذلك.يضيف هذا المكون معالجًا إلى System.AppDomain.CurrentDomain.UnhandledException ولكن بقدر ما أستطيع أن أقول أن هذا لا يحقق أي شيء للفوز بخدمة Windows لذلك انتهى بي الأمر بهذا النمط في نقطتي إدخال الخدمة (أو 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 الخاص بي باستخدام السباكة الفوضوية في التعامل مع الاستثناءات؟

هل كانت مفيدة؟

المحلول

حسنًا، لقد أجريت المزيد من البحث في هذا الآن.عندما تقوم بإنشاء خدمة Windows في .Net، فإنك تقوم بإنشاء فئة ترث من System.ServiceProcess.ServiceBase (في VB يكون هذا مخفيًا في ملف .Designer.vb).يمكنك بعد ذلك تجاوز وظيفة OnStart وOnStop، وOnPause وOnContinue إذا اخترت ذلك.يتم استدعاء هذه الأساليب من داخل الفئة الأساسية لذلك قمت بالبحث قليلاً باستخدام العاكس.يتم استدعاء OnStart بواسطة أسلوب في System.ServiceProcess.ServiceBase يسمى ServiceQueuedMainCallback.يتم إلغاء ترجمة الإصدار الموجود على جهازي "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 من كتلة Try Catch، أفترض أن أي شيء يحدث داخل أسلوب OnStart يتم تغليفه بشكل فعال بواسطة كتلة Try Catch وبالتالي فإن أي استثناءات تحدث لا يتم التعامل معها تقنيًا يتم التعامل معها فعليًا في ServiceQueuedMainCallback Try Catch.لذا فإن CurrentDomain.UnhandledException لا يحدث أبدًا على الأقل أثناء روتين بدء التشغيل.يتم استدعاء نقاط الإدخال الثلاثة الأخرى (OnStop وOnPause وOnContinue) من الفئة الأساسية بطريقة مماثلة.

لذلك "أعتقد" أن هذا يفسر سبب عدم قدرة مكون معالجة الاستثناءات الخاص بي على اكتشاف UnhandledException عند البدء والإيقاف، لكنني لست متأكدًا مما إذا كان هذا يفسر سبب عدم تمكن أجهزة ضبط الوقت التي تم إعدادها في OnStart من التسبب في UnhandledException عند إطلاقها.

نصائح أخرى

يمكنك الاشتراك في حدث AppDomain.UnhandledException.إذا كان لديك حلقة رسالة، يمكنك ربطها بـ حدث Application.ThreadException.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top