text:
//******************************************************************************************************
//  OutputAdapterCollection.cs - Gbtc
//
//  Copyright © 2010, Grid Protection Alliance.  All Rights Reserved.
//
//  Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See
//  the NOTICE file distributed with this work for additional information regarding copyright ownership.
//  The GPA licenses this file to you under the Eclipse Public License -v 1.0 (the "License"); you may
//  not use this file except in compliance with the License. You may obtain a copy of the License at:
//
//      http://www.opensource.org/licenses/eclipse-1.0.php
//
//  Unless agreed to in writing, the subject software distributed under the License is distributed on an
//  "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the
//  License for the specific language governing permissions and limitations.
//
//  Code Modification History:
//  ----------------------------------------------------------------------------------------------------
//  09/02/2010 - J. Ritchie Carroll
//       Generated original version of source code.
//
//******************************************************************************************************

using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Threading;

namespace GSF.TimeSeries.Adapters
{
    /// <summary>
    /// Represents a collection of <see cref="IOutputAdapter"/> implementations.
    /// </summary>
    public class OutputAdapterCollection : AdapterCollectionBase<IOutputAdapter>, IOutputAdapter
    {
        #region [ Members ]

        // Events

        /// <summary>
        /// Event is raised every five seconds allowing host to track total number of unprocessed measurements.
        /// </summary>
        /// <remarks>
        /// <para>
        /// Each <see cref="IOutputAdapter"/> implementation reports its current queue size of unprocessed
        /// measurements so that if queue size reaches an unhealthy threshold, host can take evasive action.
        /// </para>
        /// <para>
        /// <see cref="EventArgs{T}.Argument"/> is total number of unprocessed measurements.
        /// </para>
        /// </remarks>
        public event EventHandler<EventArgs<int>> UnprocessedMeasurements;

        #endregion

        #region [ Constructors ]

        /// <summary>
        /// Creates a new <see cref="OutputAdapterCollection"/>.
        /// </summary>
        public OutputAdapterCollection()
            : this(null)
        {
            // When collection is spawned as an adapter, it needs a parameterless constructor
        }

        /// <summary>
        /// Creates a new <see cref="OutputAdapterCollection"/>.
        /// </summary>
        /// <param name="waitHandles">Wait handle dictionary.</param>
        public OutputAdapterCollection(ConcurrentDictionary<string, AutoResetEvent> waitHandles)
            : base(waitHandles)
        {
            base.Name = "Output Adapter Collection";
            base.DataMember = "OutputAdapters";
            base.MonitorTimerEnabled = true;
        }

        #endregion

        #region [ Properties ]

        /// <summary>
        /// Gets the total number of measurements processed and destined for archive thus far by each
        /// <see cref="IOutputAdapter"/> implementation in the <see cref="OutputAdapterCollection"/>.
        /// </summary>
        public override long ProcessedMeasurements
        {
            get
            {
                long processedMeasurements = 0;

                // Calculate new total for all archive destined output adapters
                lock (this)
                {
                    foreach (IOutputAdapter item in this)
                    {
                        if (item.OutputIsForArchive)
                            processedMeasurements += item.ProcessedMeasurements;
                    }
                }

                return processedMeasurements;
            }
        }

        /// <summary>
        /// Returns a flag that determines if all measurements sent to this <see cref="OutputAdapterCollection"/> are
        /// destined for archival.
        /// </summary>
        public virtual bool OutputIsForArchive
        {
            get
            {
                lock (this)
                {
                    foreach (IOutputAdapter item in this)
                    {
                        if (item.OutputIsForArchive)
                            return true;
                    }
                }

                return false;
            }
        }

        #endregion

        #region [ Methods ]

        /// <summary>
        /// Queues a collection of measurements for processing to each <see cref="IOutputAdapter"/> implementation in
        /// this <see cref="OutputAdapterCollection"/>.
        /// </summary>
        /// <param name="measurements">Measurements to queue for processing.</param>
        public virtual void QueueMeasurementsForProcessing(IEnumerable<IMeasurement> measurements)
        {
            try
            {
                lock (this)
                {
                    foreach (IOutputAdapter item in this)
                    {
                        item.QueueMeasurementsForProcessing(measurements);
                    }
                }
            }
            catch (Exception ex)
            {
                OnProcessException(new InvalidOperationException("Failed to queue measurements to output adapters: " + ex.Message, ex));
            }
        }

        /// <summary>
        /// This function removes a range of measurements from the internal measurement queues. Note that the requested
        /// <paramref name="total"/> will be removed from each <see cref="IOutputAdapter"/> implementation in this
        /// <see cref="OutputAdapterCollection"/>.
        /// </summary>
        /// <param name="total">Total measurements to remove from the each <see cref="IOutputAdapter"/> queue.</param>
        /// <remarks>
        /// This method is typically only used to curtail size of measurement queue if it's getting too large.  If more points are
        /// requested than there are points available - all points in the queue will be removed.
        /// </remarks>
        public virtual void RemoveMeasurements(int total)
        {
            lock (this)
            {
                foreach (IOutputAdapter item in this)
                {
                    if (item.Enabled)
                        item.RemoveMeasurements(total);
                }
            }
        }

        /// <summary>
        /// Raises the <see cref="UnprocessedMeasurements"/> event.
        /// </summary>
        /// <param name="unprocessedMeasurements">Total measurements in the queue that have not been processed.</param>
        protected virtual void OnUnprocessedMeasurements(int unprocessedMeasurements)
        {
            try
            {
                if (UnprocessedMeasurements != null)
                    UnprocessedMeasurements(this, new EventArgs<int>(unprocessedMeasurements));
            }
            catch (Exception ex)
            {
                // We protect our code from consumer thrown exceptions
                OnProcessException(new InvalidOperationException(string.Format("Exception in consumer handler for UnprocessedMeasurements event: {0}", ex.Message), ex));
            }
        }

        /// <summary>
        /// Wires events and initializes new <see cref="IOutputAdapter"/> implementation.
        /// </summary>
        /// <param name="item">New <see cref="IOutputAdapter"/> implementation.</param>
        protected override void InitializeItem(IOutputAdapter item)
        {
            if (item != null)
            {
                // Wire up unprocessed measurements event
                item.UnprocessedMeasurements += item_UnprocessedMeasurements;
                base.InitializeItem(item);
            }
        }

        /// <summary>
        /// Unwires events and disposes of <see cref="IOutputAdapter"/> implementation.
        /// </summary>
        /// <param name="item"><see cref="IOutputAdapter"/> to dispose.</param>
        protected override void DisposeItem(IOutputAdapter item)
        {
            if (item != null)
            {
                // Un-wire unprocessed measurements event
                item.UnprocessedMeasurements -= item_UnprocessedMeasurements;
                base.DisposeItem(item);
            }
        }

        // Raise unprocessed measurements event on behalf of each item in collection
        private void item_UnprocessedMeasurements(object sender, EventArgs<int> e)
        {
            if (UnprocessedMeasurements != null)
                UnprocessedMeasurements(sender, e);
        }

        #endregion
    }
}


text:
@interface NetWorkingTool : AFHTTPSessionManager
+(NetWorkingTool*)shareManager;
+(NetWorkingTool*)shareImageManager;
@end

redpajama_set_name: RedPajamaGithub