CK.Core.CriticalErrorCollector.DoRaiseInBackground C# (CSharp) Method

DoRaiseInBackground() public method

public DoRaiseInBackground ( object unusedState ) : void
unusedState object
return void
        void DoRaiseInBackground( object unusedState )
        {
            int raisedCount = 0;
            bool again;
            do
            {
                again = false;
                // This lock guaranties that no more than one event will fire at the same time.
                // Since we capture the errors to raise from inside it, it also guaranties that
                // listeners will receive errors in order.
                lock( _raiseLock )
                {
                    Interlocked.Exchange( ref _dispatchWorkItemIsReady, 0 ); 
                    ErrorEventArgs e = CreateEvent();
                    if( e != null )
                    {
                        raisedCount += e.LoggingErrors.Count;
                        // Thread-safe (C# 4.0 compiler use CompareExchange).
                        var h = OnErrorFromBackgroundThreads;
                        if( h != null )
                        {
                            // h.GetInvocationList() creates an independent copy of Delegate[].
                            foreach( EventHandler<ErrorEventArgs> d in h.GetInvocationList() )
                            {
                                try
                                {
                                    d( this, e );
                                }
                                catch( Exception ex2 )
                                {
                                    // Since this thread will loop, flags it to avoid 
                                    // creating useless new dispatching queue items.
                                    Interlocked.Exchange( ref _dispatchWorkItemIsReady, 1 );
                                    Interlocked.Increment( ref _waitingRaiseCount );
                                    OnErrorFromBackgroundThreads -= (EventHandler<ErrorEventArgs>)d;
                                    lock( _collector )
                                    {
                                        if( _collector.Count == _collector.Capacity ) Interlocked.Increment( ref _lostErrorCount );
                                        else _collector.Push( new Error( Impl.CoreResources.ErrorWhileCollectorRaiseError, ex2, _seqNumber++, _lostErrorCount ) );
                                    }
                                    again = true;
                                }
                            }
                        }
                    }
                }
            }
            while( again );

            // Signals the _endOfWorkLock monitor if _waitingRaiseCount reached 0.
            if( Interlocked.Add( ref _waitingRaiseCount, -raisedCount ) == 0 )
            {
                lock( _endOfWorkLock ) Monitor.PulseAll( _endOfWorkLock );
            }
        }