Beispiel #1
0
        /// <summary>
        /// Configures the specified pipeline stage to receive log messages, when the current stage has completed running
        /// its <see cref="ProcessMessage"/> method. The method must return <c>true</c> to call the following stage.
        /// The pipeline stage must use the same log configuration as the current stage and it must not be initialized, yet.
        /// </summary>
        /// <param name="stage">The pipeline stage that should follow the current stage.</param>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="stage"/> is <c>null</c>.
        /// </exception>
        /// <exception cref="ArgumentException">
        /// <paramref name="stage"/> is already initialized or its configuration is not the same as the configuration of the current state.
        /// </exception>
        public void AddNextStage(ProcessingPipelineStage stage)
        {
            if (stage == null)
            {
                throw new ArgumentNullException(nameof(stage));
            }
            if (stage.IsInitialized)
            {
                throw new ArgumentException("The stage to add must not be initialized.", nameof(stage));
            }
            if (!ReferenceEquals(stage.Configuration, Configuration))
            {
                throw new ArgumentException("The stage must use the same configuration as the current stage.", nameof(stage));
            }

            lock (Sync)
            {
                var oldNextStages = mNextStages;
                var copy          = new ProcessingPipelineStage[mNextStages.Length + 1];
                Array.Copy(mNextStages, copy, mNextStages.Length);
                copy[copy.Length - 1] = stage;
                mNextStages           = copy;

                // initialize the added stage, if this stage is initialized
                if (mInitialized)
                {
                    try
                    {
                        stage.Initialize();
                    }
                    catch (Exception)
                    {
                        try
                        {
                            stage.Shutdown();
                        }
                        catch (Exception ex)
                        {
                            // swallow exception to avoid crashing the application, if the exception is not handled properly
                            Debug.Fail("The pipeline stage threw an exception while shutting down", ex.ToString());
                        }

                        mNextStages = oldNextStages;
                        throw;
                    }
                }
            }
        }