This collector keeps Capacity Errors (and no more). It raises OnErrorFromBackgroundThreads event on each Add. It is totally thread-safe and guaranties (as long as its Capacity is big enough) that no error can be lost (even errors raised while dispatching the event are themselves collected) and that errors are dispatched in sequence.

This class is typically used as a static property or field by any object that must handle unexpected errors. (It can also be used per-instance if it makes sense.)

示例#1
0
 static ActivityMonitor()
 {
     CriticalErrorCollector  = new CriticalErrorCollector();
     AutoConfiguration       = null;
     _defaultFilterLevel     = LogFilter.Undefined;
     _lockDefaultFilterLevel = new object();
 }
 static void OnTrackActivityMonitorLoggingError( object sender, CriticalErrorCollector.ErrorEventArgs e )
 {
     foreach( var error in e.LoggingErrors )
     {
         string s = DumpErrorText( DateTimeStamp.UtcNow, error.Comment, LogLevel.Error, error.Exception, null );
         HandleError( s );
     }
 }
 void BuggyOnErrorHandler( object source, CriticalErrorCollector.ErrorEventArgs e )
 {
     // Force at least one error regardless of the probability.
     if( _buggyOnErrorHandlerFailCount == 0 || _random.NextDouble() < _probBuggyOnErrorHandlerFailure )
     {
         // Subscribe again to this buggy event.
         ActivityMonitor.CriticalErrorCollector.OnErrorFromBackgroundThreads += BuggyOnErrorHandler;
         throw new CKException( "BuggyErrorHandler{0}", _buggyOnErrorHandlerFailCount++ );
     }
 }
        void SafeOnErrorHandler( object source, CriticalErrorCollector.ErrorEventArgs e )
        {
            if( _inSafeErrorHandler )
            {
                _errorsFromBackground.Add( "Error events are not raised simultaneously." );
                return;
            }
            
            // As soon as the first error, we increase the capacity to avoid losing any error.
            // This tests the tread-safety of the operation and shows that no deadlock occur (we are 
            // receiving an error event and can safely change the internal buffer capacity).
            ActivityMonitor.CriticalErrorCollector.Capacity = 500;

            _inSafeErrorHandler = true;
            _maxNumberOfErrorReceivedAtOnce = Math.Max( _maxNumberOfErrorReceivedAtOnce, e.LoggingErrors.Count );
            foreach( var error in e.LoggingErrors )
            {
                if( error.SequenceNumber % 10 == 0 )
                {
                    int clearedErrors;
                    int notYetRaisedErrors;
                    ActivityMonitor.CriticalErrorCollector.Clear( out clearedErrors, out notYetRaisedErrors );
                    _nbClearedWhileRaised += clearedErrors;
                    _nbNotClearedWhileRaised += notYetRaisedErrors;
                }
                if( _lastSequenceNumberReceived != error.SequenceNumber - 1 )
                {
                    _errorsFromBackground.Add( String.Format( "Received {0}, expected {1}.", error.SequenceNumber - 1, _lastSequenceNumberReceived ) );
                    _inSafeErrorHandler = false;
                    return;
                }
                _lastSequenceNumberReceived = error.SequenceNumber;
                string msg = error.Exception.Message;

                if( msg.StartsWith( "BuggyClient" ) )
                {
                    int idx = Int32.Parse( Regex.Match( msg, "\\d+" ).Value );
                    _buggyClients[idx].FailureHasBeenReceivedThroughEvent = true;
                }
                else if( msg.StartsWith( "BuggyErrorHandler" ) )
                {
                    ++_buggyOnErrorHandlerReceivedCount;
                    if( !error.ToString().StartsWith( Impl.CoreResources.ErrorWhileCollectorRaiseError ) )
                    {
                        _errorsFromBackground.Add( "Bad comment for error handling." );
                        _inSafeErrorHandler = false;
                        return;
                    }
                }
                else
                {
                    _errorsFromBackground.Add( "Unexpected error: " + error.Exception.Message );
                    _inSafeErrorHandler = false;
                    return;
                }
            }
            _inSafeErrorHandler = false;
        }