2017-03-15 1 views
0

Bonjour, J'effectue des tests d'intégration dans une application que je développe. L'élément spécifique qui provoque un problème est un appel à un agent d'arrière-plan qui interroge une base de données Oracle. Lorsqu'une erreur est rencontrée dans la requête, je souhaite que le détail de l'exception percole la pile d'appels au niveau de l'application et fournisse à ce moment un message compatible avec l'utilisateur approprié. Dans le test d'exemple, il y a une erreur de syntaxe dans le SQL sous-jacente qui se traduit par une exception OraEx:Exception non gérée dans le travail en arrière-plan

Oracle.DataAccess.Client.OracleException ORA-00907: missing right parenthesis 

Malheureusement, le code génère l'exception suivante:

System.Reflection.TargetInvocationException was unhandled 
Message: An unhandled exception of type 
'System.Reflection.TargetInvocationException' occurred in mscorlib.dll 
Additional information: Exception has been thrown by the target of an 
invocation. 

dans la sous DoWork du BackgroundWorker, malgré ma conviction que je gère correctement l'exception. C'est assez évident que je manque quelque chose de fondamental ici, quelqu'un peut-il suggérer une solution s'il vous plaît.

Merci à l'avance Paul J.

Voici le code qui fait l'appel au travailleur de fond:

Private Sub EventSearch(ByVal mySQL As String) 

    Const procName As String = "EventSearch" 

    Try 
     _eventMngr = New ScadaEventManager(_CurrentDB, _userName, _myPwd) 
     _eventMngr.SQL = mySQL 

     'Set the flag and stop query tool status accordingly 
     _Stopped = False 
     uxStopQueryTool.Enabled = True 

     'activate the timer object to ensure that the execute query menu 
     'and tool remain disabled until all background processing is complete 
     uxBackWorkTimer.Enabled = True 

     _logger.SendLog(Me.Name & "." & procName & " - Scanning for data.", NLog.LogLevel.Trace) 
     ReviseStatus(2, "Scanning for data. Please wait...", Color.Black, True, True) 

     'Force the thread to sleep for half a second so the user can see the scanning state taking place 
     Threading.Thread.Sleep(500) 

     'Launch the background worker to retrieve the required data from the database 
     uxBWScan.RunWorkerAsync(_eventMngr) 

    Catch ex As Exception 

     MsgBox(ex.Message, MsgBoxStyle.Exclamation, My.Application.Info.ProductName) 
     _logger.SendLog(ex.Message & ". Thrown in module " & Me.Name.ToString & "." & procName, NLog.LogLevel.Error, ex) 
     Call ResetStatus() 

    Finally 

    End Try 

End Sub 

Et voici le code exécuté par le travailleur de fond:

Private Sub uxBWScan_DoWork(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles uxBWScan.DoWork 
    Const procName As String = "uxBWScan_DoWork" 
    Try 
     e.Argument.CountRecords(_queryTypeID) 
     e.Result = e.Argument.RecordCount 
    Catch NullEx As NullReferenceException 
     _logger.SendLog(NullEx.Message & ". Thrown in module " & Me.Name.ToString & "." & procName, NLog.LogLevel.Error, NullEx) 
     Throw 
    Catch OraEx As OracleException 
     _logger.SendLog(OraEx.Message & ". Thrown in module " & Me.Name.ToString & "." & procName, NLog.LogLevel.Error, OraEx) 
     Throw 
    Finally 
    End Try 
End Sub 

Et voici le code de bas niveau qui génère l'erreur:

Public Sub CountRecords(ByVal queryType As Integer) 

     _myDataset = New DataSet 
     Try 
      _myDataset = _myScadaEventDB.CountRecords(_sqlText) 
      If _myDataset.Tables(0).Rows.Count > 0 Then 
       If queryType = Enums.QueryType.General Or queryType = Enums.QueryType.KeyPerformanceIndicators Or queryType = Enums.QueryType.TelecontroAnalysis Then 
        _recordCount = _myDataset.Tables(0).Rows(0).Item("RecordCount") 
       Else 
        'The query is grouped therefore count the number of records in the table 
        _recordCount = _myDataset.Tables(0).Rows.Count 
       End If 
      Else 
       _recordCount = 0 
      End If 
     Catch ex As Exception 
      Throw 
     Finally 

     End Try 

    End Sub 
+0

Vérifiez l'exception interne pour obtenir plus de détails (et très probablement l'exception que vous attendez de voir). – N0Alias

+1

Lorsque vous appelez 'CountRecords' sur l'argument de l'événement, est-ce une liaison anticipée ou une liaison tardive? Quel est le type de 'e.Argument'? Je suspecte que ceci pourrait être un appel lié tardivement, ainsi l'exception étant enveloppée dans une exception 'TargetInvocationException'. Selon le commentaire ci-dessus, vous pouvez regarder le 'InnerException' de la' TargetInvocationException' pour voir si c'est ce que vous attendiez. – Craig

+0

@Craig: C'est un appel en retard. La propriété [** 'DoWorkEventArgs.Argument' ** **] (https://msdn.microsoft.com/en-us/library/system.componentmodel.doworkeventargs.argument (v = vs.110) .aspx) est un' Objet –

Répondre

0

Ok, problème résolu. Suppression du bloc try catch de DoWork et déplacement de ma gestion des exceptions dans RunWorkerCompleted à l'aide de e.error. Une lecture de la documentation (RTFM ...) a mis en évidence le fait que l'utilisation de Try/Catch dans le thread de travail interfère avec la fonctionnalité native de BackgroundWorker. Merci encore à tous pour votre contribution.

Paul,