ConcurrentAsyncQueue 2012-07-21


# define stopwatch
//# define datetime
//# define long
namespace Test
{
    using System;
    using System.Threading;
    using System.Threading.Tasks;
    using Microshaoft;
    class Program
    {
        static void Main()
        {
            GCNotifier.RegisterForFullGCNotification
                                (
                                    99
                                    , 99
                                    , 10
                                    , (x) =>
                                    {
                                        //if (x != GCNotificationStatus.Timeout)
                                        {
                                            Console.WriteLine("FullGCApproach {0}", x);
                                        }
                                    }
                                    , (x) =>
                                    {
                                        //if (x != GCNotificationStatus.Timeout)
                                        {
                                            Console.WriteLine("FullGCComplete {0}", x);
                                        }
                                    }
                                );
            var q = new ConcurrentAsyncQueue<int>();
            q.AttachPerformanceCounters
                                (
                                    "new"
                                    , "Microshaoft ConcurrentAsyncQueue Performance Counters"
                                    , new PerformanceCountersContainer()
                                 );
            Random random = new Random();
            q.OnDequeue += new ConcurrentAsyncQueue<int>.QueueEventHandler
                                                    (
                                                        (x) =>
                                                        {
                                                            int sleep = random.Next(0, 9) * 50;
                                                            //Console.WriteLine(sleep);
                                                            //Thread.Sleep(sleep);
                                                            if (sleep > 400)
                                                            {
                                                                Console.WriteLine(x);
                                                            }
                                                        }
                                                    );
            q.OnException += new ConcurrentAsyncQueue<int>.ExceptionEventHandler
                                                                    (
                                                                        (x) =>
                                                                        {
                                                                            Console.WriteLine(x.ToString());
                                                                        }
                                                                    );
            Console.WriteLine("begin ...");
            //q.StartAdd(10);
            string r = string.Empty;
            while ((r = Console.ReadLine()) != "q")
            {
                int i;
                if (int.TryParse(r, out i))
                {
                    Console.WriteLine("Parallel Enqueue {0} begin ...", i);
                    new Thread
                            (
                                new ParameterizedThreadStart
                                            (
                                                (x) =>
                                                {
                                                    Parallel.For
                                                                (
                                                                    0
                                                                    , i
                                                                    , (xx) =>
                                                                    {
                                                                        q.Enqueue(xx);
                                                                    }
                                                                );
                                                    Console.WriteLine("Parallel Enqueue {0} end ...", i);
                                                }
                                            )
                            ).Start();
                }
                else if (r.ToLower() == "stop")
                {
                    q.StartStop(10);
                }
                else if (r.ToLower() == "add")
                {
                    q.StartAdd(20);
                }
                else
                {
                    Console.WriteLine("please input Number!");
                }
            }
        }
    }
}
namespace Microshaoft
{
    using System;
    using System.Collections.Concurrent;
    using System.Diagnostics;
    using System.Threading;
    public class ConcurrentAsyncQueue<T>
    {
        public delegate void QueueEventHandler(T item);
        public event QueueEventHandler OnDequeue;
        public delegate void QueueLogEventHandler(string logMessage);
        public QueueLogEventHandler
                                OnQueueLog
                                , OnDequeueThreadStart
                                , OnDequeueThreadEnd;
        public delegate void ExceptionEventHandler(Exception exception);
        public event ExceptionEventHandler OnException;
        private ConcurrentQueue
                            <
                                Tuple
                                    <
#if stopwatch
                                        Stopwatch
#elif datetime
                                        DateTime?
#elif long
                                        long
#endif
                                        , T
                                    >
                            > _queue =
                                    new ConcurrentQueue
                                                <
                                                    Tuple
                                                        <
#if stopwatch
                                                            Stopwatch
#elif datetime
                                                            DateTime?
#elif long
                                                            long
#endif
, T
                                                        >
                                                >();
        private ConcurrentQueue<Action> _callbackProcessBreaksActions;
        private long _concurrentDequeueThreadsCount = 0; //Microshaoft 用于控制并发线程数
        private ConcurrentQueue<ThreadProcessor> _dequeueThreadsProcessorsPool;
        private int _dequeueIdleSleepSeconds = 10;
        public PerformanceCountersContainer PerformanceCounters
        {
            get;
            private set;
        }
        public int DequeueIdleSleepSeconds
        {
            set
            {
                _dequeueIdleSleepSeconds = value;
            }
            get
            {
                return _dequeueIdleSleepSeconds;
            }
        }
        private bool _isAttachedPerformanceCounters = false;
        private class ThreadProcessor
        {
            public bool Break
            {
                set;
                get;
            }
            public EventWaitHandle Wait
            {
                private set;
                get;
            }
            public ConcurrentAsyncQueue<T> Sender
            {
                private set;
                get;
            }
            public void StopOne()
            {
                Break = true;
            }
            public ThreadProcessor
                            (
                                ConcurrentAsyncQueue<T> queue
                                , EventWaitHandle wait
                            )
            {
                Wait = wait;
                Sender = queue;
            }
            public void ThreadProcess()
            {
                Interlocked.Increment(ref Sender._concurrentDequeueThreadsCount);
                bool counterEnabled = Sender._isAttachedPerformanceCounters;
                if (counterEnabled)
                {
                    Sender.PerformanceCounters.DequeueThreadStartPerformanceCounter.ChangeCounterValueWithTryCatchExceptionFinally<long>
                                                (
                                                    counterEnabled
                                                    , (x) =>
                                                    {
                                                        return x.Increment();
                                                    }
                                                );
                    Sender.PerformanceCounters.DequeueThreadsCountPerformanceCounter.Increment();
                }
                long r = 0;
                try
                {
                    if (Sender.OnDequeueThreadStart != null)
                    {
                        r = Interlocked.Read(ref Sender._concurrentDequeueThreadsCount);
                        Sender.OnDequeueThreadStart
                                        (
                                            string.Format
                                                    (
                                                        "{0} Threads Count {1},Queue Count {2},Current Thread: {3} at {4}"
                                                        , "Threads ++ !"
                                                        , r
                                                        , Sender._queue.Count
                                                        , Thread.CurrentThread.Name
                                                        , DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fffff")
                                                    )
                                        );
                    }
                    while (true)
                    {
                        #region while true loop
                        if (Break)
                        {
                            break;
                        }
                        while (!Sender._queue.IsEmpty)
                        {
                            #region while queue.IsEmpty loop
                            if (Break)
                            {
                                break;
                            }
#if stopwatch
                            Tuple<Stopwatch, T>
#elif datetime
                            Tuple<DateTime?,T>
#elif long
                            Tuple<long,T>
#endif
                            item = null;
                            if (Sender._queue.TryDequeue(out item))
                            {
                                if (counterEnabled)
                                {
                                    Sender.PerformanceCounters.DequeuePerformanceCounter.Increment();
                                    Sender.PerformanceCounters.QueueLengthPerformanceCounter.Decrement();
                                }
                                if (Sender.OnDequeue != null)
                                {
                                    if (counterEnabled)
                                    {
                                        var beginTimeStopwatch = item.Item1;
                                        if
                                            (
#if stopwatch
                                                beginTimeStopwatch != null
#elif datetime
                                                beginTimeStopwatch != null
#elif long
                                                beginTimeStopwatch != 0
#endif
                                            )
                                        {
#if stopwatch
                                            beginTimeStopwatch.Stop();
#endif
                                            long elapsedTicks =
#if stopwatch
                                            beginTimeStopwatch.ElapsedTicks;
                                            beginTimeStopwatch = null;
#elif datetime
                                            DateTime.Now.Ticks - beginTimeStopwatch.Value.Ticks;
                                            beginTimeStopwatch = null;
#elif long
                                            DateTime.Now.Ticks - beginTimeStopwatch;
#endif
                                            Sender.PerformanceCounters.QueuedWaitAverageTimerPerformanceCounter.IncrementBy(elapsedTicks);
                                            Sender.PerformanceCounters.QueuedWaitAverageBasePerformanceCounter.Increment();
                                        }
                                    }
                                    var element = item.Item2;
                                    item = null;
                                    Sender.PerformanceCounters.DequeueProcessedAverageTimerPerformanceCounter.ChangeAverageTimerCounterValueWithTryCatchExceptionFinally
                                            (
                                                counterEnabled
                                                , Sender.PerformanceCounters.DequeueProcessedAverageBasePerformanceCounter
                                                , () =>
                                                {
                                                    Sender.OnDequeue(element);
                                                }
                                            );
                                }
                                if (Sender._isAttachedPerformanceCounters)
                                {
                                    Sender.PerformanceCounters.DequeueProcessedPerformanceCounter.Increment();
                                    Sender.PerformanceCounters.DequeueProcessedRateOfCountsPerSecondPerformanceCounter.Increment();
                                }
                            }
                            #endregion while queue.IsEmpty loop
                        }
                        #region wait
                        Sender._dequeueThreadsProcessorsPool.Enqueue(this);
                        if (Break)
                        {
                        }
                        if (!Wait.WaitOne(Sender.DequeueIdleSleepSeconds * 1000))
                        {
                        }
                        #endregion wait
                        #endregion while true loop
                    }
                }
                catch (Exception e)
                {
                    if (Sender.OnException != null)
                    {
                        Sender.OnException(e);
                    }
                }
                finally
                {
                    r = Interlocked.Decrement(ref Sender._concurrentDequeueThreadsCount);
                    if (r < 0)
                    {
                        Interlocked.Exchange(ref Sender._concurrentDequeueThreadsCount, 0);
                        if (Sender._isAttachedPerformanceCounters)
                        {
                            if (Sender.PerformanceCounters.DequeueThreadsCountPerformanceCounter.RawValue < 0)
                            {
                                Sender.PerformanceCounters.DequeueThreadsCountPerformanceCounter.RawValue = Sender._concurrentDequeueThreadsCount;
                            }
                        }
                    }
                    if (Sender.OnDequeueThreadEnd != null)
                    {
                        Sender.OnDequeueThreadEnd
                                    (
                                        string.Format
                                                (
                                                    "{0} Threads Count {1},Queue Count {2},Current Thread: {3} at {4}"
                                                    , "Threads--"
                                                    , r
                                                    , Sender._queue.Count
                                                    , Thread.CurrentThread.Name
                                                    , DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fffff")
                                                )
                                    );
                    }
                    if (Sender._isAttachedPerformanceCounters)
                    {
                        Sender.PerformanceCounters.DequeueThreadEndPerformanceCounter.Increment();
                        Sender.PerformanceCounters.DequeueThreadsCountPerformanceCounter.Decrement();
                    }
                    if (!Break)
                    {
                        Sender.StartAdd(1);
                    }
                    Break = false;
                }
            }
        }
        public void AttachPerformanceCounters
                            (
                                string instanceNamePrefix
                                , string categoryName
                                , PerformanceCountersContainer performanceCounters
                            )
        {
            var process = Process.GetCurrentProcess();
            var processName = process.ProcessName;
            var instanceName = string.Format
                                    (
                                        "{0}-{1}"
                                        , instanceNamePrefix
                                        , processName
                                    );
            PerformanceCounters = performanceCounters;
            PerformanceCounters.AttachPerformanceCountersToProperties(instanceName, categoryName);
            _isAttachedPerformanceCounters = true;
        }
        public int Count
        {
            get
            {
                return _queue.Count;
            }
        }
        public long ConcurrentThreadsCount
        {
            get
            {
                return _concurrentDequeueThreadsCount;
            }
        }
        private void Stop(int count)
        {
            Action action;
            for (var i = 0; i < count; i++)
            {
                if (_callbackProcessBreaksActions.TryDequeue(out action))
                {
                    action();
                    action = null;
                }
            }
        }
        public void StartStop(int count)
        {
            new Thread
                    (
                        new ThreadStart
                                (
                                    () =>
                                    {
                                        Stop(count);
                                    }
                                )
                    ).Start();
        }
        public void StartAdd(int count)
        {
            new Thread
                    (
                        new ThreadStart
                                (
                                    () =>
                                    {
                                        Add(count);
                                    }
                                )
                    ).Start();
        }
        private void Add(int count)
        {
            for (int i = 0; i < count; i++)
            {
                Interlocked.Increment(ref _concurrentDequeueThreadsCount);
                if (_dequeueThreadsProcessorsPool == null)
                {
                    _dequeueThreadsProcessorsPool = new ConcurrentQueue<ThreadProcessor>();
                }
                var processor = new ThreadProcessor
                                                (
                                                    this
                                                    , new AutoResetEvent(false)
                                                );
                var thread = new Thread
                                    (
                                        new ThreadStart
                                                    (
                                                        processor.ThreadProcess
                                                    )
                                    );
                if (_callbackProcessBreaksActions == null)
                {
                    _callbackProcessBreaksActions = new ConcurrentQueue<Action>();
                }
                var callbackProcessBreakAction = new Action
                                                        (
                                                            processor.StopOne
                                                        );
                _callbackProcessBreaksActions.Enqueue(callbackProcessBreakAction);
                _dequeueThreadsProcessorsPool.Enqueue(processor);
                thread.Start();
            }
        }
        public void Enqueue(T item)
        {
            try
            {
#if stopwatch
                Stopwatch stopwatch = null;
#elif datetime
                DateTime? stopwatch = null;
#elif long
                long stopwatch = 0;
#endif
                if (_isAttachedPerformanceCounters)
                {
#if stopwatch
                    stopwatch = Stopwatch.StartNew();
#elif datetime
                    stopwatch  = DateTime.Now;
#elif long
                    stopwatch  = DateTime.Now.Ticks;
#endif
                }
                var element = Tuple.Create
                                        <
#if stopwatch
                                            Stopwatch
#elif datetime
                                            DateTime?
#elif long
                                            long
#endif
                                            , T
                                        >(stopwatch, item);
                _queue.Enqueue(element);
                if (_isAttachedPerformanceCounters)
                {
                    PerformanceCounters.EnqueuePerformanceCounter.Increment();
                    PerformanceCounters.EnqueueRateOfCountsPerSecondPerformanceCounter.Increment();
                    PerformanceCounters.QueueLengthPerformanceCounter.Increment();
                }
                if
                    (
                        _dequeueThreadsProcessorsPool != null
                        && !_dequeueThreadsProcessorsPool.IsEmpty
                    )
                {
                    ThreadProcessor processor;
                    if (_dequeueThreadsProcessorsPool.TryDequeue(out processor))
                    {
                        processor.Wait.Set();
                        processor = null;
                        //Console.WriteLine("processor = null;");
                    }
                }
            }
            catch (Exception e)
            {
                if (OnException != null)
                {
                    OnException(e);
                }
            }
        }
    }
}
namespace Microshaoft
{
    using System.Diagnostics;
    public static class PerformanceCounterHelper
    {
        public static CounterCreationData GetCounterCreationData(string counterName, PerformanceCounterType performanceCounterType)
        {
            return new CounterCreationData()
            {
                CounterName = counterName
                ,
                CounterHelp = string.Format("{0} Help", counterName)
                ,
                CounterType = performanceCounterType
            };
        }
    }
}
namespace Microshaoft
{
    using System;
    using System.Diagnostics;
    public static class PerformanceCounterExtensionMethodsManager
    {
        public static T ChangeCounterValueWithTryCatchExceptionFinally<T>
                                (
                                    this PerformanceCounter performanceCounter
                                    , bool enabled
                                    , Func<PerformanceCounter, T> OnCounterChangeProcessFunc = null
                                    , Action<PerformanceCounter> OnCounterChangedProcessAction = null
                                    , Func<PerformanceCounter, Exception, bool> OnCatchedExceptionProcessFunc = null
                                    , Action<PerformanceCounter> OnCatchedExceptionFinallyProcessAction = null
                                )
        {
            T r = default(T);
            if (enabled)
            {
                if (OnCounterChangeProcessFunc != null)
                {
                    var catchedException = false;
                    try
                    {
                        r = OnCounterChangeProcessFunc(performanceCounter);
                    }
                    catch (Exception e)
                    {
                        catchedException = true;
                        if (OnCatchedExceptionProcessFunc != null)
                        {
                            var b = OnCatchedExceptionProcessFunc(performanceCounter, e);
                            if (b)
                            {
                                throw new Exception("OnCounterChangeProcessFunc InnerExcepion", e);
                            }
                        }
                    }
                    finally
                    {
                        if (catchedException)
                        {
                            if (OnCatchedExceptionFinallyProcessAction != null)
                            {
                                OnCatchedExceptionFinallyProcessAction(performanceCounter);
                            }
                        }
                    }
                }
            }
            if (OnCounterChangedProcessAction != null)
            {
                var catchedException = false;
                try
                {
                    OnCounterChangedProcessAction(performanceCounter);
                }
                catch (Exception e)
                {
                    catchedException = true;
                    if (OnCatchedExceptionProcessFunc != null)
                    {
                        var b = OnCatchedExceptionProcessFunc(performanceCounter, e);
                        if (b)
                        {
                            throw new Exception("OnCounterChangedProcessAction InnerExcepion", e);
                        }
                    }
                }
                finally
                {
                    if (catchedException)
                    {
                        if (OnCatchedExceptionFinallyProcessAction != null)
                        {
                            OnCatchedExceptionFinallyProcessAction(performanceCounter);
                        }
                    }
                }
            }
            return r;
        }
        public static void ChangeAverageTimerCounterValueWithTryCatchExceptionFinally
                                                        (
                                                            this PerformanceCounter performanceCounter
                                                            , bool enabled
                                                            , PerformanceCounter basePerformanceCounter
                                                            , Action OnCounterInnerProcessAction = null
                                                            , Func<PerformanceCounter, Exception, bool> OnCatchedExceptionProcessFunc = null
                                                            , Action<PerformanceCounter, PerformanceCounter> OnCatchedExceptionFinallyProcessAction = null
                                                        )
        {
            if (enabled)
            {
                var stopwatch = Stopwatch.StartNew();
                if (OnCounterInnerProcessAction != null)
                {
                    var catchedException = false;
                    try
                    {
                        OnCounterInnerProcessAction();
                    }
                    catch (Exception e)
                    {
                        catchedException = true;
                        if (OnCatchedExceptionProcessFunc != null)
                        {
                            var b = OnCatchedExceptionProcessFunc(performanceCounter, e);
                            if (b)
                            {
                                throw new Exception("OnCounterInnerProcessAction InnerExcepion", e);
                            }
                        }
                    }
                    finally
                    {
                        stopwatch.Stop();
                        performanceCounter.IncrementBy(stopwatch.ElapsedTicks);
                        stopwatch = null;
                        basePerformanceCounter.Increment();
                        if (catchedException)
                        {
                            if (OnCatchedExceptionFinallyProcessAction != null)
                            {
                                OnCatchedExceptionFinallyProcessAction(performanceCounter, basePerformanceCounter);
                            }
                        }
                    }
                }
            }
        }
    }
}
namespace Microshaoft
{
    using System;
    using System.Diagnostics;
    using System.Linq;
    using System.Collections.Concurrent;
    public class PerformanceCountersContainer
    {
        #region PerformanceCounters
        private PerformanceCounter _enqueuePerformanceCounter;
        [PerformanceCounterTypeAttribute(CounterType = PerformanceCounterType.NumberOfItems64)]
        public PerformanceCounter EnqueuePerformanceCounter
        {
            private set
            {
                ReaderWriterLockSlimHelper.TryEnterWriterLockSlimWrite<PerformanceCounter>(ref _enqueuePerformanceCounter, value, 2);
            }
            get
            {
                return _enqueuePerformanceCounter;
            }
        }
        private PerformanceCounter _enqueueRateOfCountsPerSecondPerformanceCounter;
        [PerformanceCounterTypeAttribute(CounterType = PerformanceCounterType.RateOfCountsPerSecond64)]
        public PerformanceCounter EnqueueRateOfCountsPerSecondPerformanceCounter
        {
            private set
            {
                ReaderWriterLockSlimHelper.TryEnterWriterLockSlimWrite<PerformanceCounter>(ref _enqueueRateOfCountsPerSecondPerformanceCounter, value, 2);
            }
            get
            {
                return _enqueueRateOfCountsPerSecondPerformanceCounter;
            }
        }
        private PerformanceCounter _dequeuePerformanceCounter;
        [PerformanceCounterTypeAttribute(CounterType = PerformanceCounterType.NumberOfItems64)]
        public PerformanceCounter DequeuePerformanceCounter
        {
            private set
            {
                ReaderWriterLockSlimHelper.TryEnterWriterLockSlimWrite<PerformanceCounter>(ref _dequeuePerformanceCounter, value, 2);
            }
            get
            {
                return _dequeuePerformanceCounter;
            }
        }
        private PerformanceCounter _dequeueProcessedRateOfCountsPerSecondPerformanceCounter;
        [PerformanceCounterTypeAttribute(CounterType = PerformanceCounterType.RateOfCountsPerSecond64)]
        public PerformanceCounter DequeueProcessedRateOfCountsPerSecondPerformanceCounter
        {
            private set
            {
                ReaderWriterLockSlimHelper.TryEnterWriterLockSlimWrite<PerformanceCounter>(ref _dequeueProcessedRateOfCountsPerSecondPerformanceCounter, value, 2);
            }
            get
            {
                return _dequeueProcessedRateOfCountsPerSecondPerformanceCounter;
            }
        }
        private PerformanceCounter _dequeueProcessedPerformanceCounter;
        [PerformanceCounterTypeAttribute(CounterType = PerformanceCounterType.NumberOfItems64)]
        public PerformanceCounter DequeueProcessedPerformanceCounter
        {
            private set
            {
                ReaderWriterLockSlimHelper.TryEnterWriterLockSlimWrite<PerformanceCounter>(ref _dequeueProcessedPerformanceCounter, value, 2);
            }
            get
            {
                return _dequeueProcessedPerformanceCounter;
            }
        }
        private PerformanceCounter _dequeueProcessedAverageTimerPerformanceCounter;
        [PerformanceCounterTypeAttribute(CounterType = PerformanceCounterType.AverageTimer32)]
        public PerformanceCounter DequeueProcessedAverageTimerPerformanceCounter
        {
            private set
            {
                ReaderWriterLockSlimHelper.TryEnterWriterLockSlimWrite<PerformanceCounter>(ref _dequeueProcessedAverageTimerPerformanceCounter, value, 2);
            }
            get
            {
                return _dequeueProcessedAverageTimerPerformanceCounter;
            }
        }
        private PerformanceCounter _dequeueProcessedAverageBasePerformanceCounter;
        [PerformanceCounterTypeAttribute(CounterType = PerformanceCounterType.AverageBase)]
        public PerformanceCounter DequeueProcessedAverageBasePerformanceCounter
        {
            private set
            {
                ReaderWriterLockSlimHelper.TryEnterWriterLockSlimWrite<PerformanceCounter>(ref _dequeueProcessedAverageBasePerformanceCounter, value, 2);
            }
            get
            {
                return _dequeueProcessedAverageBasePerformanceCounter;
            }
        }
        private PerformanceCounter _queuedWaitAverageTimerPerformanceCounter;
        [PerformanceCounterTypeAttribute(CounterType = PerformanceCounterType.AverageTimer32)]
        public PerformanceCounter QueuedWaitAverageTimerPerformanceCounter
        {
            private set
            {
                ReaderWriterLockSlimHelper.TryEnterWriterLockSlimWrite<PerformanceCounter>(ref _queuedWaitAverageTimerPerformanceCounter, value, 2);
            }
            get
            {
                return _queuedWaitAverageTimerPerformanceCounter;
            }
        }
        private PerformanceCounter _queuedWaitAverageBasePerformanceCounter;
        [PerformanceCounterTypeAttribute(CounterType = PerformanceCounterType.AverageBase)]
        public PerformanceCounter QueuedWaitAverageBasePerformanceCounter
        {
            private set
            {
                ReaderWriterLockSlimHelper.TryEnterWriterLockSlimWrite<PerformanceCounter>(ref _queuedWaitAverageBasePerformanceCounter, value, 2);
            }
            get
            {
                return _queuedWaitAverageBasePerformanceCounter;
            }
        }
        private PerformanceCounter _queueLengthPerformanceCounter;
        [PerformanceCounterTypeAttribute(CounterType = PerformanceCounterType.NumberOfItems64)]
        public PerformanceCounter QueueLengthPerformanceCounter
        {
            private set
            {
                ReaderWriterLockSlimHelper.TryEnterWriterLockSlimWrite<PerformanceCounter>(ref _queueLengthPerformanceCounter, value, 2);
            }
            get
            {
                return _queueLengthPerformanceCounter;
            }
        }
        private PerformanceCounter _dequeueThreadStartPerformanceCounter;
        [PerformanceCounterTypeAttribute(CounterType = PerformanceCounterType.NumberOfItems64)]
        public PerformanceCounter DequeueThreadStartPerformanceCounter
        {
            private set
            {
                ReaderWriterLockSlimHelper.TryEnterWriterLockSlimWrite<PerformanceCounter>(ref _dequeueThreadStartPerformanceCounter, value, 2);
            }
            get
            {
                return _dequeueThreadStartPerformanceCounter;
            }
        }
        private PerformanceCounter _dequeueThreadEndPerformanceCounter;
        [PerformanceCounterTypeAttribute(CounterType = PerformanceCounterType.NumberOfItems64)]
        public PerformanceCounter DequeueThreadEndPerformanceCounter
        {
            private set
            {
                ReaderWriterLockSlimHelper.TryEnterWriterLockSlimWrite<PerformanceCounter>(ref _dequeueThreadEndPerformanceCounter, value, 2);
            }
            get
            {
                return _dequeueThreadEndPerformanceCounter;
            }
        }
        private PerformanceCounter _dequeueThreadsCountPerformanceCounter;
        [PerformanceCounterTypeAttribute(CounterType = PerformanceCounterType.NumberOfItems64)]
        public PerformanceCounter DequeueThreadsCountPerformanceCounter
        {
            private set
            {
                ReaderWriterLockSlimHelper.TryEnterWriterLockSlimWrite<PerformanceCounter>(ref _dequeueThreadsCountPerformanceCounter, value, 2);
            }
            get
            {
                return _dequeueThreadsCountPerformanceCounter;
            }
        }
        #endregion
        // indexer declaration
        public PerformanceCounter this[string name]
        {
            get
            {
                throw new NotImplementedException();
                //return null;
            }
        }
        private bool _isAttachedPerformanceCounters = false;
        public void AttachPerformanceCountersToProperties
                            (
                                string instanceName
                                , string categoryName
                            )
        {
            if (!_isAttachedPerformanceCounters)
            {
                var type = this.GetType();
                PerformanceCountersHelper.AttachPerformanceCountersToProperties<PerformanceCountersContainer>(instanceName, categoryName, this);
            }
            _isAttachedPerformanceCounters = true;
        }
    }
}
namespace Microshaoft
{
    using System;
    using System.Diagnostics;
    [AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = false)]
    public class PerformanceCounterTypeAttribute : Attribute
    {
        public PerformanceCounterType CounterType;
    }
}
namespace Microshaoft
{
    using System.Diagnostics;
    using System.Linq;
    public static class PerformanceCountersHelper
    {
        public static void AttachPerformanceCountersToProperties<T>
                                    (
                                        string performanceCounterInstanceName
                                        , string category
                                        , T target = default(T)
                                    )
        {
            var type = typeof(T);
            var propertiesList = type.GetProperties().ToList();
            propertiesList = propertiesList.Where
                                                (
                                                    (pi) =>
                                                    {
                                                        var parameters = pi.GetIndexParameters();
                                                        return
                                                            (
                                                                pi.PropertyType == typeof(PerformanceCounter)
                                                                && (parameters == null ? 0 : parameters.Length) <= 0
                                                            );
                                                    }
                                                ).ToList();
            if (PerformanceCounterCategory.Exists(category))
            {
                propertiesList.ForEach
                                    (
                                        (pi) =>
                                        {
                                            if (PerformanceCounterCategory.CounterExists(pi.Name, category))
                                            {
                                                if (PerformanceCounterCategory.InstanceExists(performanceCounterInstanceName, category))
                                                {
                                                    //var pc = new PerformanceCounter(category, pi.Name, instanceName, false);
                                                    //pc.InstanceName = instanceName;
                                                    //pc.RemoveInstance();
                                                }
                                            }
                                        }
                                    );
                PerformanceCounterCategory.Delete(category);
            }
            var ccdc = new CounterCreationDataCollection();
            propertiesList.ForEach
                            (
                                (pi) =>
                                {
                                    var propertyName = pi.Name;
                                    PerformanceCounterTypeAttribute attribute = pi.GetCustomAttributes(false).FirstOrDefault
                                                                                (
                                                                                    (x) =>
                                                                                    {
                                                                                        return x as PerformanceCounterTypeAttribute != null;
                                                                                    }
                                                                                ) as PerformanceCounterTypeAttribute;
                                    PerformanceCounterType performanceCounterType = (attribute == null ? PerformanceCounterType.NumberOfItems64 : attribute.CounterType);
                                    var ccd = PerformanceCounterHelper.GetCounterCreationData
                                    (
                                        propertyName
                                        , performanceCounterType
                                    );
                                    ccdc.Add(ccd);
                                }
                            );
            PerformanceCounterCategory.Create
                            (
                                category,
                                string.Format("{0} Category Help.", category),
                                PerformanceCounterCategoryType.MultiInstance,
                                ccdc
                            );
            propertiesList.ForEach
                            (
                                (pi) =>
                                {
                                    var propertyName = pi.Name;
                                    var pc = new PerformanceCounter()
                                    {
                                        CategoryName = category
                                        ,
                                        CounterName = propertyName
                                        ,
                                        InstanceLifetime = PerformanceCounterInstanceLifetime.Process
                                        ,
                                        InstanceName = performanceCounterInstanceName
                                        ,
                                        ReadOnly = false
                                        ,
                                        RawValue = 0
                                    };
                                    if (pi.GetGetMethod().IsStatic)
                                    {
                                        var setter = DynamicPropertyAccessor.CreateSetStaticPropertyValueAction<PerformanceCounter>(type, propertyName);
                                        setter(pc);
                                    }
                                    else
                                    {
                                        if (target != null)
                                        {
                                            var setter = DynamicPropertyAccessor.CreateSetPropertyValueAction<PerformanceCounter>(type, propertyName);
                                            setter(target, pc);
                                        }
                                    }
                                }
                            );
        }
    }
}
namespace Microshaoft
{
    using System;
    using System.Threading;
    public static class ReaderWriterLockSlimHelper
    {
        public static bool TryEnterWriterLockSlimWrite<T>
                                                (
                                                     ref T target
                                                    , T newValue
                                                    , int enterTimeOutSeconds
                                                )
                                                    where T : class
        {
            bool r = false;
            var rwls = new ReaderWriterLockSlim();
            int timeOut = Timeout.Infinite;
            if (enterTimeOutSeconds >= 0)
            {
                timeOut = enterTimeOutSeconds * 1000;
            }
            try
            {
                r = (rwls.TryEnterWriteLock(timeOut));
                if (r)
                {
                    Interlocked.Exchange<T>(ref target, newValue);
                    r = true;
                }
            }
            finally
            {
                if (r)
                {
                    rwls.ExitWriteLock();
                }
            }
            return r;
        }
        public static bool TryEnterWriterLockSlim
                                (
                                    Action action
                                    , int enterTimeOutSeconds
                                )
        {
            bool r = false;
            if (action != null)
            {
                var rwls = new ReaderWriterLockSlim();
                int timeOut = Timeout.Infinite;
                if (enterTimeOutSeconds >= 0)
                {
                    timeOut = enterTimeOutSeconds * 1000;
                }
                try
                {
                    r = (rwls.TryEnterWriteLock(timeOut));
                    if (r)
                    {
                        action();
                        r = true;
                    }
                }
                finally
                {
                    if (r)
                    {
                        rwls.ExitWriteLock();
                    }
                }
            }
            return r;
        }
    }
}
namespace Microshaoft
{
    using System;
    using System.Threading;
    public static class GCNotifier
    {
        public static void CancelForFullGCNotification()
        {
            GC.CancelFullGCNotification();
        }
        public static void RegisterForFullGCNotification
                                    (
                                        int maxGenerationThreshold
                                        , int maxLargeObjectHeapThreshold
                                        , int waitOnceSecondsTimeout
                                        , Action<GCNotificationStatus> waitForFullGCApproachProcessAction
                                        , Action<GCNotificationStatus> waitForFullGCCompleteProcessAction
                                    )
        {
            GC.RegisterForFullGCNotification(maxGenerationThreshold, maxLargeObjectHeapThreshold);
            new Thread
                    (
                        new ThreadStart
                                (
                                    () =>
                                    {
                                        while (true)
                                        {
                                            if (waitForFullGCApproachProcessAction != null)
                                            {
                                                var gcNotificationStatus = GC.WaitForFullGCApproach(1000 * waitOnceSecondsTimeout);
                                                if (gcNotificationStatus != GCNotificationStatus.Timeout)
                                                {
                                                    waitForFullGCApproachProcessAction(gcNotificationStatus);
                                                }
                                            }
                                            if (waitForFullGCApproachProcessAction != null)
                                            {
                                                var gcNotificationStatus = GC.WaitForFullGCComplete(1000 * waitOnceSecondsTimeout);
                                                if (gcNotificationStatus != GCNotificationStatus.Timeout)
                                                {
                                                    waitForFullGCCompleteProcessAction(gcNotificationStatus);
                                                }
                                            }
                                            Thread.Sleep(1000);
                                        }
                                    }
                                )
                        ).Start();
        }
    }
}
namespace Microshaoft
{
    using System;
    using System.Linq;
    using System.Linq.Expressions;
    public class DynamicPropertyAccessor
    {
        public static Func<object, object> CreateGetPropertyValueFunc(string typeName, string propertyName, bool isTypeFromAssembly = false)
        {
            Type type;
            if (isTypeFromAssembly)
            {
                var assembly = AppDomain.CurrentDomain.GetAssemblies().First
                                                                (
                                                                    (a) =>
                                                                    {
                                                                        return a.GetTypes().Any
                                                                                            (
                                                                                                (t) =>
                                                                                                {
                                                                                                    return (t.FullName == typeName);
                                                                                                }
                                                                                            );
                                                                    }
                                                                );
                type = assembly.GetType(typeName);
            }
            else
            {
                type = Type.GetType(typeName);
            }
            return CreateGetPropertyValueFunc(type, propertyName);
        }
        public static Func<object, object> CreateGetPropertyValueFunc(Type type, string propertyName)
        {
            var target = Expression.Parameter(typeof(object));
            var castTarget = Expression.Convert(target, type);
            var getPropertyValue = Expression.Property(castTarget, propertyName);
            var castPropertyValue = Expression.Convert(getPropertyValue, typeof(object));
            var lambda = Expression.Lambda<Func<object, object>>(castPropertyValue, target);
            return lambda.Compile();
        }
        public static Func<object, TProperty> CreateGetPropertyValueFunc<TProperty>(string typeName, string propertyName, bool isTypeFromAssembly = false)
        {
            Type type;
            if (isTypeFromAssembly)
            {
                var assembly = AppDomain.CurrentDomain.GetAssemblies().First
                                                                (
                                                                    (a) =>
                                                                    {
                                                                        return a.GetTypes().Any
                                                                                            (
                                                                                                (t) =>
                                                                                                {
                                                                                                    return (t.FullName == typeName);
                                                                                                }
                                                                                            );
                                                                    }
                                                                );
                type = assembly.GetType(typeName);
            }
            else
            {
                type = Type.GetType(typeName);
            }
            return CreateGetPropertyValueFunc<TProperty>(type, propertyName);
        }
        public static Func<object, TProperty> CreateGetPropertyValueFunc<TProperty>(Type type, string propertyName)
        {
            var target = Expression.Parameter(typeof(object));
            var castTarget = Expression.Convert(target, type);
            var getPropertyValue = Expression.Property(castTarget, propertyName);
            var lambda = Expression.Lambda<Func<object, TProperty>>(getPropertyValue, target);
            return lambda.Compile();
        }
        public static Func<TProperty> CreateGetStaticPropertyValueFunc<TProperty>(string typeName, string propertyName, bool isTypeFromAssembly = false)
        {
            Type type;
            if (isTypeFromAssembly)
            {
                var assembly = AppDomain.CurrentDomain.GetAssemblies().First
                                                                (
                                                                    (a) =>
                                                                    {
                                                                        return a.GetTypes().Any
                                                                                            (
                                                                                                (t) =>
                                                                                                {
                                                                                                    return (t.FullName == typeName);
                                                                                                }
                                                                                            );
                                                                    }
                                                                );
                type = assembly.GetType(typeName);
            }
            else
            {
                type = Type.GetType(typeName);
            }
            return CreateGetStaticPropertyValueFunc<TProperty>(type, propertyName);
        }
        public static Func<TProperty> CreateGetStaticPropertyValueFunc<TProperty>(Type type, string propertyName)
        {
            var property = type.GetProperty(propertyName, typeof(TProperty));
            var getPropertyValue = Expression.Property(null, property);
            var lambda = Expression.Lambda<Func<TProperty>>(getPropertyValue, null);
            return lambda.Compile();
        }
        public static Func<object> CreateGetStaticPropertyValueFunc(Type type, string propertyName)
        {
            var property = type.GetProperty(propertyName);
            var getPropertyValue = Expression.Property(null, property);
            var castPropertyValue = Expression.Convert(getPropertyValue, typeof(object));
            var lambda = Expression.Lambda<Func<object>>(castPropertyValue, null);
            return lambda.Compile();
        }
        public static Func<object> CreateGetStaticPropertyValueFunc(string typeName, string propertyName, bool isTypeFromAssembly = false)
        {
            Type type;
            if (isTypeFromAssembly)
            {
                var assembly = AppDomain.CurrentDomain.GetAssemblies().First
                                                                (
                                                                    (a) =>
                                                                    {
                                                                        return a.GetTypes().Any
                                                                                            (
                                                                                                (t) =>
                                                                                                {
                                                                                                    return (t.FullName == typeName);
                                                                                                }
                                                                                            );
                                                                    }
                                                                );
                type = assembly.GetType(typeName);
            }
            else
            {
                type = Type.GetType(typeName);
            }
            return CreateGetStaticPropertyValueFunc(type, propertyName);
        }
        public static Action<object, object> CreateSetPropertyValueAction(Type type, string propertyName)
        {
            var property = type.GetProperty(propertyName);
            var target = Expression.Parameter(typeof(object));
            var propertyValue = Expression.Parameter(typeof(object));
            var castTarget = Expression.Convert(target, type);
            var castPropertyValue = Expression.Convert(propertyValue, property.PropertyType);
            var getSetMethod = property.GetSetMethod();
            if (getSetMethod == null)
            {
                getSetMethod = property.GetSetMethod(true);
            }
            var call = Expression.Call(castTarget, getSetMethod, castPropertyValue);
            var lambda = Expression.Lambda<Action<object, object>>(call, target, propertyValue);
            return lambda.Compile();
        }
        public static Action<object, object> CreateSetPropertyValueAction(string typeName, string propertyName, bool isTypeFromAssembly = false)
        {
            Type type;
            if (isTypeFromAssembly)
            {
                var assembly = AppDomain.CurrentDomain.GetAssemblies().First
                                                                (
                                                                    (a) =>
                                                                    {
                                                                        return a.GetTypes().Any
                                                                                            (
                                                                                                (t) =>
                                                                                                {
                                                                                                    return (t.FullName == typeName);
                                                                                                }
                                                                                            );
                                                                    }
                                                                );
                type = assembly.GetType(typeName);
            }
            else
            {
                type = Type.GetType(typeName);
            }
            return CreateSetPropertyValueAction(type, propertyName);
        }
        public static Action<object, TProperty> CreateSetPropertyValueAction<TProperty>(Type type, string propertyName)
        {
            var property = type.GetProperty(propertyName);
            var target = Expression.Parameter(typeof(object));
            var propertyValue = Expression.Parameter(typeof(TProperty));
            var castTarget = Expression.Convert(target, type);
            var castPropertyValue = Expression.Convert(propertyValue, property.PropertyType);
            var getSetMethod = property.GetSetMethod();
            if (getSetMethod == null)
            {
                getSetMethod = property.GetSetMethod(true);
            }
            var call = Expression.Call(castTarget, getSetMethod, castPropertyValue);
            return Expression.Lambda<Action<object, TProperty>>(call, target, propertyValue).Compile();
        }
        public static Action<object, TProperty> CreateSetPropertyValueAction<TProperty>(string typeName, string propertyName, bool isTypeFromAssembly = false)
        {
            Type type;
            if (isTypeFromAssembly)
            {
                var assembly = AppDomain.CurrentDomain.GetAssemblies().First
                                                                (
                                                                    (a) =>
                                                                    {
                                                                        return a.GetTypes().Any
                                                                                            (
                                                                                                (t) =>
                                                                                                {
                                                                                                    return (t.FullName == typeName);
                                                                                                }
                                                                                            );
                                                                    }
                                                                );
                type = assembly.GetType(typeName);
            }
            else
            {
                type = Type.GetType(typeName);
            }
            return CreateSetPropertyValueAction<TProperty>(type, propertyName);
        }
        public static Action<object> CreateSetStaticPropertyValueAction(Type type, string propertyName)
        {
            var property = type.GetProperty(propertyName);
            var propertyValue = Expression.Parameter(typeof(object));
            var castPropertyValue = Expression.Convert(propertyValue, property.PropertyType);
            var getSetMethod = property.GetSetMethod();
            if (getSetMethod == null)
            {
                getSetMethod = property.GetSetMethod(true);
            }
            var call = Expression.Call(null, getSetMethod, castPropertyValue);
            var lambda = Expression.Lambda<Action<object>>(call, propertyValue);
            return lambda.Compile();
        }
        public static Action<object> CreateSetStaticPropertyValueAction(string typeName, string propertyName, bool isTypeFromAssembly = false)
        {
            Type type;
            if (isTypeFromAssembly)
            {
                var assembly = AppDomain.CurrentDomain.GetAssemblies().First
                                                                (
                                                                    (a) =>
                                                                    {
                                                                        return a.GetTypes().Any
                                                                                            (
                                                                                                (t) =>
                                                                                                {
                                                                                                    return (t.FullName == typeName);
                                                                                                }
                                                                                            );
                                                                    }
                                                                );
                type = assembly.GetType(typeName);
            }
            else
            {
                type = Type.GetType(typeName);
            }
            return CreateSetStaticPropertyValueAction(type, propertyName);
        }
        public static Action<TProperty> CreateSetStaticPropertyValueAction<TProperty>(Type type, string propertyName)
        {
            var property = type.GetProperty(propertyName);
            var propertyValue = Expression.Parameter(typeof(TProperty));
            //var castPropertyValue = Expression.Convert(propertyValue, property.PropertyType);
            var getSetMethod = property.GetSetMethod();
            if (getSetMethod == null)
            {
                getSetMethod = property.GetSetMethod(true);
            }
            var call = Expression.Call(null, getSetMethod, propertyValue);
            var lambda = Expression.Lambda<Action<TProperty>>(call, propertyValue);
            return lambda.Compile();
        }
        public static Action<TProperty> CreateSetStaticPropertyValueAction<TProperty>(string typeName, string propertyName, bool isTypeFromAssembly = false)
        {
            Type type;
            if (isTypeFromAssembly)
            {
                var assembly = AppDomain.CurrentDomain.GetAssemblies().First
                                                                (
                                                                    (a) =>
                                                                    {
                                                                        return a.GetTypes().Any
                                                                                            (
                                                                                                (t) =>
                                                                                                {
                                                                                                    return (t.FullName == typeName);
                                                                                                }
                                                                                            );
                                                                    }
                                                                );
                type = assembly.GetType(typeName);
            }
            else
            {
                type = Type.GetType(typeName);
            }
            return CreateSetStaticPropertyValueAction<TProperty>(type, propertyName);
        }
    }
}

posted @ 2012-07-21 09:16  于斯人也  阅读(219)  评论(0编辑  收藏  举报