0

我通过为System.Windows.Forms.Application.ThreadException. 我对我的日志记录的可靠性相当有信心,但这让我想知道是什么原因造成的。此外,当服务器速度如此之慢导致超时时,有多少Exceptions人可以登录到服务器上。

基本上,有几个实例是我们的 SQL 服务器在一天中进行导入过程,而用户收到SqlExceptionsException.Message超时已过期。在操作完成之前超时时间已过或服务器没有响应”。现在,在此期间记录的大多数异常都正常间隔,但在 3 个不同的日子里,一个客户SqlException在几分钟内记录了数千个异常。

所以我问:

  1. 日志记录代码是否是生成这么多异常记录的罪魁祸首
  2. 如果System.Data.SqlClient幕后有任何东西可以产生这么多,以及是否有任何配置可以防止这种情况发生。
  3. 如果事件处理中有任何东西可能导致事件被重发这么多次。

日志记录函数的调用是一条直线,这让我相信它实际上捕获了数千个异常,尽管我无法理解会生成多少异常。

但是,记录器中有一个后备循环,我想知道这是否是原因。虽然在我的测试中,在异常处理程序中未捕获的异常会导致程序崩溃,所以我在异常处理期间看不到异常,然后自己处理和记录。此外,21.5k 总堆栈跟踪中没有一个表明处理程序中发生了异常。

所以这里是记录器本身的代码:(注意tries和相关的逻辑是一个新的添加,以防止潜在的无限循环)

    ''' <summary>
    ''' Tries to log an Exception to the database.
    ''' </summary>
    ''' <param name="out">The results of Exception handling</param>
    ''' <param name="ex">The Exception to log.</param>
    ''' <param name="customMessage">A custom message to append to the Exception's message when logging to DB.</param>
    Private Shared Sub LogException(ByVal out As ExceptionLogOutcome, ByVal ex As Exception, Optional ByVal customMessage As String = "", Optional ByVal priority As ExceptionDE.Priority = ExceptionDE.Priority.Medium)
        If ex IsNot Nothing Then

            out.ExceptionDataEntity = New DataEntity.ExceptionDE(ex, priority, CurrentBatchAuditDate, CurrentMachineID, CurrentBatchID, CurrentDocNum, CurrentTransactionID, CurrentUser)

            If customMessage.Length > 0 Then
                out.ExceptionDataEntity.Message &= " NOTE: " & customMessage
            End If

            Dim retry As Boolean = False
            Dim tries As Integer = 0
            Do
                Try
                    DataAccess.LoggerDAO.CreateExceptionLog(out.ExceptionDataEntity)
                Catch exc As SqlClient.SqlException
                    retry = MsgBox(String.Format("An error occured while logging an exception in the program.  Retry?"), MsgBoxStyle.RetryCancel) = MsgBoxResult.Retry

                    If Not retry Then
                        'Failure logging
                        out.WasLogged = False
                        Return
                    End If
                Catch exc As Exception
                    out.LoggingException = exc
                    out.WasLogged = False
                    Return
                End Try
            Loop While retry And tries < 10
        Else
            'Ex is nothing
            out.WasLogged = False
            Return
        End If

        out.WasLogged = True
        Return
    End Sub

然而,进一步导致我排除我自己的代码是问题的原因是,我在 21.5k 重复记录上做了一个 select distinctSqlExceptions并且只返回了 4 个唯一的堆栈跟踪,没有一个表明在处理期间发生了异常,并且没有一个在任何类型的循环。2 个在Keydown触发 Sql 查询代码的处理程序内,一个在Load触发查询的处理程序内,一个在Click事件内。

这是两个堆栈跟踪,除了客户端代码 FWIW:

at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection)
at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj)
at System.Data.SqlClient.TdsParserStateObject.ReadSniError(TdsParserStateObject stateObj, UInt32 error)
at System.Data.SqlClient.TdsParserStateObject.ReadSni(DbAsyncResult asyncResult, TdsParserStateObject stateObj)
at System.Data.SqlClient.TdsParserStateObject.ReadNetworkPacket()
at System.Data.SqlClient.TdsParser.ConsumePreLoginHandshake(Boolean encrypt, Boolean trustServerCert, Boolean& marsCapable)
at System.Data.SqlClient.TdsParser.Connect(ServerInfo serverInfo, SqlInternalConnectionTds connHandler, Boolean ignoreSniOpenTimeout, Int64 timerExpire, Boolean encrypt, Boolean trustServerCert, Boolean integratedSecurity, SqlConnection owningObject)
at System.Data.SqlClient.SqlInternalConnectionTds.AttemptOneLogin(ServerInfo serverInfo, String newPassword, Boolean ignoreSniOpenTimeout, Int64 timerExpire, SqlConnection owningObject)
at System.Data.SqlClient.SqlInternalConnectionTds.LoginNoFailover(String host, String newPassword, Boolean redirectedUserInstance, SqlConnection owningObject, SqlConnectionString connectionOptions, Int64 timerStart)
at System.Data.SqlClient.SqlInternalConnectionTds.OpenLoginEnlist(SqlConnection owningObject, SqlConnectionString connectionOptions, String newPassword, Boolean redirectedUserInstance)
at System.Data.SqlClient.SqlInternalConnectionTds..ctor(DbConnectionPoolIdentity identity, SqlConnectionString connectionOptions, Object providerInfo, String newPassword, SqlConnection owningObject, Boolean redirectedUserInstance)
at System.Data.SqlClient.SqlConnectionFactory.CreateConnection(DbConnectionOptions options, Object poolGroupProviderInfo, DbConnectionPool pool, DbConnection owningConnection)
at System.Data.ProviderBase.DbConnectionFactory.CreatePooledConnection(DbConnection owningConnection, DbConnectionPool pool, DbConnectionOptions options)
at System.Data.ProviderBase.DbConnectionPool.CreateObject(DbConnection owningObject)
at System.Data.ProviderBase.DbConnectionPool.UserCreateRequest(DbConnection owningObject)
at System.Data.ProviderBase.DbConnectionPool.GetConnection(DbConnection owningObject)
at System.Data.ProviderBase.DbConnectionFactory.GetConnection(DbConnection owningConnection)
at System.Data.ProviderBase.DbConnectionClosed.OpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory)
at System.Data.SqlClient.SqlConnection.Open()

和#2

at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection)
at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj)
at System.Data.SqlClient.TdsParserStateObject.ReadSniError(TdsParserStateObject stateObj, UInt32 error)
at System.Data.SqlClient.TdsParserStateObject.ReadSni(DbAsyncResult asyncResult, TdsParserStateObject stateObj)
at System.Data.SqlClient.TdsParserStateObject.ReadNetworkPacket()
at System.Data.SqlClient.TdsParserStateObject.ReadBuffer()
at System.Data.SqlClient.TdsParserStateObject.ReadByte()
at System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj)
at System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString)
at System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async)
at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, DbAsyncResult result)
at System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(DbAsyncResult result, String methodName, Boolean sendToPipe)
at System.Data.SqlClient.SqlCommand.ExecuteNonQuery()   
4

1 回答 1

2

我将在这里四处走动,看看这是否是问题所在。

  1. 你永远不会增加你的重试计数器。(这可能不是主要问题)

  2. 如果有人按下重试,则重试值设置为 true。此值永远不会再次设置为 false。因此,如果第二次重试成功,它将无限循环,直到失败,用户可以选择取消。

于 2013-08-29T07:00:44.340 回答