• ConcurrentAsyncQueue 2014-09-07


    
    #define NET45
    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 QueuePerformanceCountersContainer()
                                     );
                Random random = new Random();
                q.OnDequeue += new ConcurrentAsyncQueue<int>
                                        .QueueEventHandler
                                            (
                                                (x) =>
                                                {
                                                    int sleep = random.Next(0, 9) * 50;
                                                    //sleep = 1000;
                                                    //Console.WriteLine(sleep);
                                                    Thread.Sleep(sleep);
                                                    if (sleep > 400)
                                                    {
                                                        Console.WriteLine(x);
                                                    }
                                                }
                                            );
                q.OnCaughtException += new ConcurrentAsyncQueue<int>
                                        .ExceptionEventHandler
                                            (
                                                (x, y) =>
                                                {
                                                    Console.WriteLine(x.ToString());
                                                    return false;
                                                }
                                            );
                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.StartDecreaseDequeueProcessThreads(10);
                    }
                    else if (r.ToLower() == "add")
                    {
                        q.StartIncreaseDequeueProcessThreads(8);
                    }
                    else
                    {
                        Console.WriteLine("please input Number!");
                    }
                }
            }
        }
    }
    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.Collections.Concurrent;
        using System.Diagnostics;
        using System.Threading;
        internal static class QueuedObjectsPoolManager
        {
            public static readonly QueuedObjectsPool<Stopwatch> StopwatchsPool = new QueuedObjectsPool<Stopwatch>(0);
        }
        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 bool ExceptionEventHandler(ConcurrentAsyncQueue<T> sender, Exception exception);
            public event ExceptionEventHandler OnCaughtException;
            private ConcurrentQueue<Tuple<Stopwatch, T>> _queue =
                                        new ConcurrentQueue<Tuple<Stopwatch, T>>();
            public ConcurrentQueue<Tuple<Stopwatch, T>> InternalQueue
            {
                get { return _queue; }
                //set { _queue = value; }
            }
            private ConcurrentQueue<Action> _callbackProcessBreaksActions;
            private long _concurrentDequeueThreadsCount = 0; //Microshaoft 用于控制并发线程数
            private ConcurrentQueue<ThreadProcessor> _dequeueThreadsProcessorsPool;
            private int _dequeueIdleSleepSeconds = 10;
            public QueuePerformanceCountersContainer 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()
                {
                    long l = 0;
                    Interlocked.Increment(ref Sender._concurrentDequeueThreadsCount);
                    bool counterEnabled = Sender._isAttachedPerformanceCounters;
                    QueuePerformanceCountersContainer qpcc = Sender.PerformanceCounters;
                    var queue = Sender.InternalQueue;
                    var reThrowException = false;
                    PerformanceCounter[] incrementCountersBeforeCountPerformanceForThread = null;
                    PerformanceCounter[] decrementCountersAfterCountPerformanceForThread = null;
                    PerformanceCounter[] incrementCountersAfterCountPerformanceForThread = null;
                    if (counterEnabled && qpcc != null)
                    {
                        incrementCountersBeforeCountPerformanceForThread =
                            new PerformanceCounter[]
                                        {
                                            qpcc
                                                .DequeueThreadStartPerformanceCounter
                                            , qpcc
                                                .DequeueThreadsCountPerformanceCounter
                                        };
                        decrementCountersAfterCountPerformanceForThread =
                            new PerformanceCounter[]
                                        {
                                            qpcc.DequeueThreadsCountPerformanceCounter
                                        };
                        incrementCountersAfterCountPerformanceForThread =
                            new PerformanceCounter[]
                                        {
                                            qpcc.DequeueThreadEndPerformanceCounter    
                                        };
                    }
                    PerformanceCountersHelper
                        .TryCountPerformance
                            (
                                counterEnabled
                                , reThrowException
                                , incrementCountersBeforeCountPerformanceForThread
                                , null
                                , null
                                , () =>
                                {
                                    #region Try Process
                                    if (Sender.OnDequeueThreadStart != null)
                                    {
                                        l = Interlocked.Read(ref Sender._concurrentDequeueThreadsCount);
                                        Sender
                                            .OnDequeueThreadStart
                                                (
                                                    string
                                                        .Format
                                                            (
                                                                "{0} Threads Count {1},Queue Count {2},Current Thread: {3} at {4}"
                                                                , "Threads ++ !"
                                                                , l
                                                                , 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 (!queue.IsEmpty)
                                        {
                                            #region while queue.IsEmpty loop
                                            if (Break)
                                            {
                                                break;
                                            }
                                            Tuple<Stopwatch, T> item = null;
                                            if (queue.TryDequeue(out item))
                                            {
                                                Stopwatch stopwatchDequeue = QueuedObjectsPoolManager.StopwatchsPool.Get();
                                                PerformanceCounter[] incrementCountersBeforeCountPerformanceForDequeue = null;
                                                PerformanceCounter[] decrementCountersBeforeCountPerformanceForDequeue = null;
                                                PerformanceCounter[] incrementCountersAfterCountPerformanceForDequeue = null;
                                                Tuple
                                                    <
                                                        bool
                                                        , Stopwatch
                                                        , PerformanceCounter
                                                        , PerformanceCounter
                                                    >[] timerCounters = null;
                                                if (counterEnabled && qpcc != null)
                                                {
                                                    incrementCountersBeforeCountPerformanceForDequeue =
                                                        new PerformanceCounter[]
                                                                        {
                                                                            qpcc
                                                                                .DequeuePerformanceCounter
                                                                        };
                                                    decrementCountersBeforeCountPerformanceForDequeue =
                                                        new PerformanceCounter[]
                                                                            {
                                                                                qpcc
                                                                                    .QueueLengthPerformanceCounter
                                                                            };
                                                    timerCounters = new Tuple
                                                                        <
                                                                            bool
                                                                            , Stopwatch
                                                                            , PerformanceCounter
                                                                            , PerformanceCounter
                                                                        >[]
                                                                    {
                                                                        Tuple.Create
                                                                                <
                                                                                    bool                    //before 时是否需要启动        
                                                                                    , Stopwatch
                                                                                    , PerformanceCounter
                                                                                    , PerformanceCounter    //base
                                                                                >
                                                                            (
                                                                                false
                                                                                , item.Item1
                                                                                , qpcc
                                                                                    .QueuedWaitAverageTimerPerformanceCounter
                                                                                , qpcc
                                                                                    .QueuedWaitAverageBasePerformanceCounter
                                                                            )
                                                                        , Tuple.Create
                                                                                <
                                                                                    bool
                                                                                    , Stopwatch
                                                                                    , PerformanceCounter
                                                                                    , PerformanceCounter
                                                                                >
                                                                            (
                                                                                true
                                                                                , stopwatchDequeue
                                                                                , qpcc
                                                                                    .DequeueProcessedAverageTimerPerformanceCounter
                                                                                , qpcc
                                                                                    .DequeueProcessedAverageBasePerformanceCounter
                                                                            )
                                                                    };
                                                    incrementCountersAfterCountPerformanceForDequeue =
                                                        new PerformanceCounter[]
                                                                    {
                                                                        qpcc
                                                                            .DequeueProcessedPerformanceCounter
                                                                        , qpcc
                                                                            .DequeueProcessedRateOfCountsPerSecondPerformanceCounter
                                                                    };
                                                }
                                                PerformanceCountersHelper
                                                    .TryCountPerformance
                                                        (
                                                            counterEnabled
                                                            , reThrowException
                                                            , incrementCountersBeforeCountPerformanceForDequeue
                                                            , decrementCountersBeforeCountPerformanceForDequeue
                                                            , timerCounters
                                                            , () =>            //try
                                                            {
                                                                if (Sender.OnDequeue != null)
                                                                {
                                                                    var element = item.Item2;
                                                                    item = null;
                                                                    Sender.OnDequeue(element);
                                                                }
                                                            }
                                                            , (x) =>        //catch
                                                            {
                                                                reThrowException = false;
                                                                return reThrowException;
                                                            }
                                                            , null            //finally
                                                            , null
                                                            , incrementCountersAfterCountPerformanceForDequeue
                                                        );
                                                //池化
                                                stopwatchDequeue.Reset();
                                                QueuedObjectsPoolManager.StopwatchsPool.Put(stopwatchDequeue);
                                            }
                                            #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
                                    }
                                    #endregion
                                }
                                , (x) =>            //catch
                                {
                                    #region Catch Process
                                    if (Sender.OnCaughtException != null)
                                    {
                                        reThrowException = Sender.OnCaughtException(Sender, x);
                                    }
                                    return reThrowException;
                                    #endregion
                                }
                                , (x, y) =>        //finally
                                {
                                    #region Finally Process
                                    l = Interlocked.Decrement(ref Sender._concurrentDequeueThreadsCount);
                                    if (l < 0)
                                    {
                                        Interlocked.Exchange(ref Sender._concurrentDequeueThreadsCount, 0);
                                    }
                                    if (Sender.OnDequeueThreadEnd != null)
                                    {
                                        Sender
                                            .OnDequeueThreadEnd
                                                (
                                                    string.Format
                                                            (
                                                                "{0} Threads Count {1},Queue Count {2},Current Thread: {3} at {4}"
                                                                , "Threads--"
                                                                , l
                                                                , Sender.InternalQueue.Count
                                                                , Thread.CurrentThread.Name
                                                                , DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fffff")
                                                            )
                                                );
                                    }
                                    if (!Break)
                                    {
                                        Sender.StartIncreaseDequeueProcessThreads(1);
                                    }
                                    Break = false;
                                    #endregion
                                }
                                , decrementCountersAfterCountPerformanceForThread
                                , incrementCountersAfterCountPerformanceForThread
                            );
                }
            }
            public void AttachPerformanceCounters
                                (
                                    string instanceNamePrefix
                                    , string categoryName
                                    , QueuePerformanceCountersContainer 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 DecreaseDequeueProcessThreads(int count)
            {
                Action action;
                for (var i = 0; i < count; i++)
                {
                    if (_callbackProcessBreaksActions.TryDequeue(out action))
                    {
                        action();
                        action = null;
                    }
                }
            }
            public void StartDecreaseDequeueProcessThreads(int count)
            {
                new Thread
                        (
                            new ThreadStart
                                    (
                                        () =>
                                        {
                                            DecreaseDequeueProcessThreads(count);
                                        }
                                    )
                        ).Start();
            }
            public void StartIncreaseDequeueProcessThreads(int count)
            {
                new Thread
                        (
                            new ThreadStart
                                    (
                                        () =>
                                        {
                                            IncreaseDequeueProcessThreads(count);
                                        }
                                    )
                        ).Start();
            }
            private void IncreaseDequeueProcessThreads(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 bool Enqueue(T item)
            {
                var r = false;
                var reThrowException = false;
                var enableCount = _isAttachedPerformanceCounters;
                PerformanceCounter[] incrementCountersBeforeCountPerformance = null;
                var qpcc = PerformanceCounters;
                if (enableCount && qpcc != null)
                {
                    incrementCountersBeforeCountPerformance =
                       new PerformanceCounter[]
                                {
                                    qpcc
                                        .EnqueuePerformanceCounter
                                    , qpcc
                                        .EnqueueRateOfCountsPerSecondPerformanceCounter
                                    , qpcc
                                        .QueueLengthPerformanceCounter
                                };
                }
                PerformanceCountersHelper
                    .TryCountPerformance
                        (
                            enableCount
                            , reThrowException
                            , incrementCountersBeforeCountPerformance
                            , null
                            , null
                            , () =>
                            {
                                Stopwatch stopwatch = null;
                                if (_isAttachedPerformanceCounters)
                                {
                                    stopwatch = QueuedObjectsPoolManager.StopwatchsPool.Get();
                                    stopwatch = Stopwatch.StartNew();
                                }
                                var element = Tuple.Create<Stopwatch, T>(stopwatch, item);
                                _queue.Enqueue(element);
                                r = true;
                            }
                            , (x) =>
                            {
                                if (OnCaughtException != null)
                                {
                                    reThrowException = OnCaughtException(this, x);
                                }
                                return reThrowException;
                            }
                            , (x, y) =>
                            {
                                if
                                    (
                                        _dequeueThreadsProcessorsPool != null
                                        && !_dequeueThreadsProcessorsPool.IsEmpty
                                    )
                                {
                                    ThreadProcessor processor;
                                    if (_dequeueThreadsProcessorsPool.TryDequeue(out processor))
                                    {
                                        processor.Wait.Set();
                                        processor = null;
                                        //Console.WriteLine("processor = null;");
                                    }
                                }
                            }
                        );
                return r;
            }
        }
    }
    namespace Microshaoft
    {
        using System;
        using System.Diagnostics;
        public class QueuePerformanceCountersContainer //: IPerformanceCountersContainer
        {
            #region PerformanceCounters
            private PerformanceCounter _caughtExceptionsPerformanceCounter;
            [
                PerformanceCounterDefinitionAttribute
                    (
                        CounterType = PerformanceCounterType.NumberOfItems64
                        , CounterName = "99.捕获异常次数(次)"
                    )
            ]
            public PerformanceCounter CaughtExceptionsPerformanceCounter
            {
                private set
                {
                    _caughtExceptionsPerformanceCounter = value;
                }
                get
                {
                    return _caughtExceptionsPerformanceCounter;
                }
            }
            private PerformanceCounter _enqueuePerformanceCounter;
            [
                PerformanceCounterDefinitionAttribute
                    (
                        CounterType = PerformanceCounterType.NumberOfItems64
                        , CounterName = "01.入队列累计总数(笔)"
                    )
            ]
            public PerformanceCounter EnqueuePerformanceCounter
            {
                private set
                {
                    _enqueuePerformanceCounter = value;
                }
                get
                {
                    return _enqueuePerformanceCounter;
                }
            }
            private PerformanceCounter _enqueueRateOfCountsPerSecondPerformanceCounter;
            [
                PerformanceCounterDefinitionAttribute
                    (
                        CounterType = PerformanceCounterType.RateOfCountsPerSecond64
                        , CounterName = "02.每秒入队列笔数(笔/秒)"
                    )
            ]
            public PerformanceCounter EnqueueRateOfCountsPerSecondPerformanceCounter
            {
                private set
                {
                    _enqueueRateOfCountsPerSecondPerformanceCounter = value;
                }
                get
                {
                    return _enqueueRateOfCountsPerSecondPerformanceCounter;
                }
            }
            private PerformanceCounter _queueLengthPerformanceCounter;
            [
                PerformanceCounterDefinitionAttribute
                    (
                        CounterType = PerformanceCounterType.NumberOfItems64
                        , CounterName = "03.队列当前长度(笔)"
                    )
            ]
            public PerformanceCounter QueueLengthPerformanceCounter
            {
                private set
                {
                    _queueLengthPerformanceCounter = value;
                }
                get
                {
                    return _queueLengthPerformanceCounter;
                }
            }
            private PerformanceCounter _dequeuePerformanceCounter;
            [
                PerformanceCounterDefinitionAttribute
                    (
                        CounterType = PerformanceCounterType.NumberOfItems64
                        , CounterName = "04.出队列累计总数(笔)"
                    )
            ]
            public PerformanceCounter DequeuePerformanceCounter
            {
                private set
                {
                    _dequeuePerformanceCounter = value;
                }
                get
                {
                    return _dequeuePerformanceCounter;
                }
            }
            private PerformanceCounter _dequeueProcessedRateOfCountsPerSecondPerformanceCounter;
            [
                PerformanceCounterDefinitionAttribute
                    (
                        CounterType = PerformanceCounterType.RateOfCountsPerSecond64
                        , CounterName = "05.每秒出队列并完成处理笔数(笔/秒)"
                    )
            ]
            public PerformanceCounter DequeueProcessedRateOfCountsPerSecondPerformanceCounter
            {
                private set
                {
                    _dequeueProcessedRateOfCountsPerSecondPerformanceCounter = value;
                }
                get
                {
                    return _dequeueProcessedRateOfCountsPerSecondPerformanceCounter;
                }
            }
            private PerformanceCounter _dequeueProcessedPerformanceCounter;
            [
                PerformanceCounterDefinitionAttribute
                    (
                        CounterType = PerformanceCounterType.NumberOfItems64
                        , CounterName = "06.已出队列并完成处理累计总笔数(笔)"
                    )
            ]
            public PerformanceCounter DequeueProcessedPerformanceCounter
            {
                private set
                {
                    _dequeueProcessedPerformanceCounter = value;
                }
                get
                {
                    return _dequeueProcessedPerformanceCounter;
                }
            }
            private PerformanceCounter _dequeueProcessedAverageTimerPerformanceCounter;
            [
                PerformanceCounterDefinitionAttribute
                    (
                        CounterType = PerformanceCounterType.AverageTimer32
                        , CounterName = "07.每笔已出队列并完成处理平均耗时秒数(秒/笔)"
                    )
            ]
            public PerformanceCounter DequeueProcessedAverageTimerPerformanceCounter
            {
                private set
                {
                    _dequeueProcessedAverageTimerPerformanceCounter = value;
                }
                get
                {
                    return _dequeueProcessedAverageTimerPerformanceCounter;
                }
            }
            private PerformanceCounter _dequeueProcessedAverageBasePerformanceCounter;
            [
                PerformanceCounterDefinitionAttribute
                    (
                        CounterType = PerformanceCounterType.AverageBase
                    )
            ]
            public PerformanceCounter DequeueProcessedAverageBasePerformanceCounter
            {
                private set
                {
                    _dequeueProcessedAverageBasePerformanceCounter = value;
                }
                get
                {
                    return _dequeueProcessedAverageBasePerformanceCounter;
                }
            }
            private PerformanceCounter _queuedWaitAverageTimerPerformanceCounter;
            [
                PerformanceCounterDefinitionAttribute
                    (
                        CounterType = PerformanceCounterType.AverageTimer32
                        , CounterName = "08.每笔入出队列并完成处理平均耗时秒数(秒/笔)"
                    )
            ]
            public PerformanceCounter QueuedWaitAverageTimerPerformanceCounter
            {
                private set
                {
                    _queuedWaitAverageTimerPerformanceCounter = value;
                }
                get
                {
                    return _queuedWaitAverageTimerPerformanceCounter;
                }
            }
            private PerformanceCounter _queuedWaitAverageBasePerformanceCounter;
            [
                PerformanceCounterDefinitionAttribute
                    (
                        CounterType = PerformanceCounterType.AverageBase
                    )
            ]
            public PerformanceCounter QueuedWaitAverageBasePerformanceCounter
            {
                private set
                {
                    _queuedWaitAverageBasePerformanceCounter = value;
                }
                get
                {
                    return _queuedWaitAverageBasePerformanceCounter;
                }
            }
            private PerformanceCounter _dequeueThreadStartPerformanceCounter;
            [
                PerformanceCounterDefinitionAttribute
                    (
                        CounterType = PerformanceCounterType.NumberOfItems64
                        , CounterName = "09.新建出队列处理线程启动次数(次)"
                    )
            ]
            public PerformanceCounter DequeueThreadStartPerformanceCounter
            {
                private set
                {
                    _dequeueThreadStartPerformanceCounter = value;
                }
                get
                {
                    return _dequeueThreadStartPerformanceCounter;
                }
            }
            private PerformanceCounter _dequeueThreadsCountPerformanceCounter;
            [
                PerformanceCounterDefinitionAttribute
                    (
                        CounterType = PerformanceCounterType.NumberOfItems64
                        , CounterName = "10.当前出队列并发处理线程数(个)"
                    )
            ]
            public PerformanceCounter DequeueThreadsCountPerformanceCounter
            {
                private set
                {
                    _dequeueThreadsCountPerformanceCounter = value;
                }
                get
                {
                    return _dequeueThreadsCountPerformanceCounter;
                }
            }
            private PerformanceCounter _dequeueThreadEndPerformanceCounter;
            [
                PerformanceCounterDefinitionAttribute
                    (
                        CounterType = PerformanceCounterType.NumberOfItems64
                        , CounterName = "11.出队列处理线程退出次数(次)"
                    )
            ]
            public PerformanceCounter DequeueThreadEndPerformanceCounter
            {
                private set
                {
                    _dequeueThreadEndPerformanceCounter = value;
                }
                get
                {
                    return _dequeueThreadEndPerformanceCounter;
                }
            }
            #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<QueuePerformanceCountersContainer>
                            (instanceName, categoryName, this);
                }
                _isAttachedPerformanceCounters = true;
            }
        }
    }
    namespace Microshaoft
    {
        using System.Collections.Concurrent;
        public class QueuedObjectsPool<T> where T: new()
        {
            private ConcurrentQueue<T> _pool = new ConcurrentQueue<T>();
            public QueuedObjectsPool(int capacity)
            {
                _pool = new ConcurrentQueue<T>();
                for (int i = 0; i < capacity; i++)
                {
                    PutNew();
                }
            }
            public void PutNew()
            {
                var e = default(T);
                e = new T();
                Put(e);
            }
            public bool Put(T target)
            {
                var r = false;
                if (target != null)
                {
                   _pool.Enqueue(target);
                   r = true;
                }
                return r;
            }
            public T Get()
            { 
                T r;
                while (!_pool.TryDequeue(out r))
                {
                    PutNew();
                }
                return r;
            }
        }
    }
    namespace Microshaoft
    {
        using System;
        using System.Diagnostics;
        public static class PerformanceCounterExtensionMethodsManager
        {
            public static void ChangeAverageTimerCounterValueWithTryCatchExceptionFinally
                                    (
                                        this PerformanceCounter performanceCounter
                                        , bool enabled
                                        , PerformanceCounter basePerformanceCounter
                                        , Stopwatch stopwatch
                                        , Action onCountPerformanceInnerProcessAction = null
                                        , Func<PerformanceCounter, Exception, bool> onCaughtExceptionProcessFunc = null
                                        , Action<PerformanceCounter, PerformanceCounter, bool, Exception> onFinallyProcessAction = null
                                    )
            {
                //Stopwatch stopwatch = null;
                if (enabled)
                {
                    stopwatch.Reset();
                    stopwatch.Start();
                }
                if (onCountPerformanceInnerProcessAction != null)
                {
                    bool reThrowException = false;
                    TryCatchFinallyProcessHelper
                        .TryProcessCatchFinally
                            (
                                true
                                , () =>
                                {
                                    onCountPerformanceInnerProcessAction();
                                }
                                , reThrowException
                                , (x, y) =>
                                {
                                    var r = reThrowException;
                                    if (onCaughtExceptionProcessFunc != null)
                                    {
                                        r = onCaughtExceptionProcessFunc(performanceCounter, x);
                                    }
                                    return r;
                                }
                                , (x, y) =>
                                {
                                    if (enabled && stopwatch != null && stopwatch.IsRunning)
                                    {
                                        stopwatch.Stop();
                                        performanceCounter.IncrementBy(stopwatch.ElapsedTicks);
                                        //stopwatch = null;
                                        basePerformanceCounter.Increment();
                                    }
                                    if (onFinallyProcessAction != null)
                                    {
                                        onFinallyProcessAction
                                            (
                                                performanceCounter
                                                , basePerformanceCounter
                                                , x
                                                , y
                                            );
                                    }
                                }
                            );
                }
            }
        }
    }
    namespace Microshaoft
    {
        using System;
        using System.Diagnostics;
        [FlagsAttribute]
        public enum MultiPerformanceCountersTypeFlags : ushort
        {
            None = 0,
            ProcessCounter = 1,
            ProcessingCounter = 2,
            ProcessedCounter = 4,
            ProcessedAverageTimerCounter = 8,
            ProcessedRateOfCountsPerSecondCounter = 16
        };
        [AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = false)]
        public class PerformanceCounterDefinitionAttribute : Attribute
        {
            public PerformanceCounterType CounterType;
            public string CounterName;
        }
    }
    namespace Microshaoft
    {
        using System;
        using System.Diagnostics;
        using System.Threading;
        using System.Linq;
        public static class PerformanceCountersHelper
        {
            public static void TryCountPerformance
                                (
                                    bool enableCount
                                    , bool reThrowException = false
                                    , PerformanceCounter[] IncrementCountersBeforeCountPerformance = null
                                    , PerformanceCounter[] DecrementCountersBeforeCountPerformance = null
                                    , Tuple
                                            <
                                                bool                        //before时是否已经启动
                                                , Stopwatch
                                                , PerformanceCounter
                                                , PerformanceCounter        //base计数器
                                            >[] timerCounters = null
                                    , Action onTryCountPerformanceProcessAction = null
                                    , Func<Exception, bool> onCaughtExceptionCountPerformanceProcessFunc = null
                                    , Action<bool, Exception> onFinallyCountPerformanceProcessAction = null
                                    , PerformanceCounter[] DecrementCountersAfterCountPerformance = null
                                    , PerformanceCounter[] IncrementCountersAfterCountPerformance = null
                                )
            {
                if (onTryCountPerformanceProcessAction != null)
                {
                    if (enableCount)
                    {
                        #region before
                        if (IncrementCountersBeforeCountPerformance != null)
                        {
                            Array.ForEach
                                    (
                                        IncrementCountersBeforeCountPerformance
                                        , (x) =>
                                        {
                                            var l = x.Increment();
                                        }
                                    );
                        }
                        if (DecrementCountersBeforeCountPerformance != null)
                        {
                            Array.ForEach
                                    (
                                        DecrementCountersBeforeCountPerformance
                                        , (x) =>
                                        {
                                            var l = x.Decrement();
                                            if (l < 0)
                                            {
                                                x.RawValue = 0;
                                            }
                                        }
                                    );
                        }
                        if (timerCounters != null)
                        {
                            Array.ForEach
                            (
                                timerCounters
                                , (x) =>
                                {
                                    if
                                        (
                                            x.Item1
                                            && x.Item2 != null
                                        )
                                    {
    #if NET45
                                        x.Item2.Restart();
    #elif NET35
                                        x.Item2.Reset();
                                        x.Item2.Start();
    #endif
                                    }
                                }
                            );
                        }
                        #endregion
                    }
                    var needTry = true;
                    TryCatchFinallyProcessHelper
                        .TryProcessCatchFinally
                            (
                                needTry
                                , () =>
                                {
                                    onTryCountPerformanceProcessAction();
                                }
                                , reThrowException
                                , (x, y) =>
                                {
                                    if (onCaughtExceptionCountPerformanceProcessFunc != null)
                                    {
                                        reThrowException = onCaughtExceptionCountPerformanceProcessFunc(x);
                                    }
                                    return reThrowException;
                                }
                                , (x, y) =>
                                {
                                    if (enableCount)
                                    {
                                        #region after
    #if NET45
                                        if (timerCounters != null)
                                        {
                                            Array.ForEach
                                            (
                                                timerCounters
                                                , (xx) =>
                                                {
                                                    if (xx.Item2 != null)
                                                    {
                                                        Stopwatch stopwatch = xx.Item2;
                                                        stopwatch.Stop();
                                                        long elapsedTicks = stopwatch.ElapsedTicks;
                                                        var counter = xx.Item3;
                                                        counter.IncrementBy(elapsedTicks);
                                                        //池化
                                                        //stopwatch = null;
                                                        counter = xx.Item4;  //base
                                                        counter.Increment();
                                                    }
                                                }
                                            );
                                        }
    #endif
                                        if (IncrementCountersAfterCountPerformance != null)
                                        {
                                            Array.ForEach
                                                    (
                                                        IncrementCountersAfterCountPerformance
                                                        , (xx) =>
                                                        {
                                                            var l = xx.Increment();
                                                        }
                                                    );
                                        }
                                        if (DecrementCountersAfterCountPerformance != null)
                                        {
                                            Array.ForEach
                                                    (
                                                        DecrementCountersAfterCountPerformance
                                                        , (xx) =>
                                                        {
                                                            var l = xx.Decrement();
                                                            if (l < 0)
                                                            {
                                                                xx.RawValue = 0;
                                                            }
                                                        }
                                                    );
                                        }
                                        #endregion
                                    }
                                    if (onFinallyCountPerformanceProcessAction != null)
                                    {
                                        onFinallyCountPerformanceProcessAction(x, y);
                                    }
                                }
                            );
                }
            }
            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);
                }
                if (!PerformanceCounterCategory.Exists(category))
                {
                    var ccdc = new CounterCreationDataCollection();
                    propertiesList
                        .ForEach
                            (
                                (pi) =>
                                {
                                    var propertyName = pi.Name;
                                    var performanceCounterType = PerformanceCounterType.NumberOfItems64;
                                    var performanceCounterName = propertyName;
                                    var attribute
                                            = pi
                                                .GetCustomAttributes(false)
                                                    .FirstOrDefault
                                                        (
                                                            (x) =>
                                                            {
                                                                return
                                                                    x as PerformanceCounterDefinitionAttribute
                                                                    != null;
                                                            }
                                                        ) as PerformanceCounterDefinitionAttribute;
                                    if (attribute != null)
                                    {
                                        var counterName = attribute.CounterName;
                                        if (!string.IsNullOrEmpty(counterName))
                                        {
                                            performanceCounterName = counterName;
                                        }
                                        var counterType = attribute.CounterType;
                                        //if (counterType != null)
                                        {
                                            performanceCounterType = counterType;
                                        }
                                    }
                                    var ccd = PerformanceCountersHelper
                                                .GetCounterCreationData
                                                    (
                                                        performanceCounterName
                                                        , performanceCounterType
                                                    );
                                    ccdc.Add(ccd);
                                }
                            );
                    PerformanceCounterCategory
                        .Create
                            (
                                category
                                , string.Format("{0} Category Help.", category)
                                , PerformanceCounterCategoryType.MultiInstance
                                , ccdc
                            );
                }
                propertiesList.ForEach
                                (
                                    (pi) =>
                                    {
                                        var propertyName = pi.Name;
                                        var performanceCounterType = PerformanceCounterType.NumberOfItems64;
                                        var performanceCounterName = propertyName;
                                        var attribute
                                                = pi
                                                    .GetCustomAttributes(false)
                                                        .FirstOrDefault
                                                            (
                                                                (x) =>
                                                                {
                                                                    return
                                                                        x as PerformanceCounterDefinitionAttribute
                                                                        != null;
                                                                }
                                                            ) as PerformanceCounterDefinitionAttribute;
                                        if (attribute != null)
                                        {
                                            var counterName = attribute.CounterName;
                                            if (!string.IsNullOrEmpty(counterName))
                                            {
                                                performanceCounterName = counterName;
                                            }
                                            var counterType = attribute.CounterType;
                                            //if (counterType != null)
                                            {
                                                performanceCounterType = counterType;
                                            }
                                        }
                                        var pc = new PerformanceCounter()
                                        {
                                            CategoryName = category
                                            ,
                                            CounterName = performanceCounterName
                                            ,
                                            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);
                                            }
                                        }
                                    }
                                );
            }
            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;
        using System.Reflection;
    #if NET45
    //#endif
        using System.Threading.Tasks;
    //#if NET45
    #endif
        public static class TryCatchFinallyProcessHelper
        {
    #if NET45
    //#endif
            public static async Task<T> TryProcessCatchFinallyAsync<T>
                                        (
                                            bool needTry
                                            , Func<Task<T>> onTryProcessFunc
                                            , bool reThrowException = false
                                            , Func<Exception, bool> onCaughtExceptionProcessFunc = null
                                            , Action<bool, Exception> onFinallyProcessAction = null
                                        )
            {
                T r = default(T);
                //if (onTryProcessAction != null)
                {
                    if (needTry)
                    {
                        Exception exception = null;
                        var caughtException = false;
                        try
                        {
                            r = await onTryProcessFunc();
                            return r;
                        }
                        catch (Exception e)
                        {
                            caughtException = true;
                            exception = e;
                            var currentCalleeMethod = MethodInfo.GetCurrentMethod();
                            var currentCalleeType = currentCalleeMethod.DeclaringType;
                            StackTrace stackTrace = new StackTrace();
                            StackFrame stackFrame = stackTrace.GetFrame(1);
                            var callerMethod = stackFrame.GetMethod();
                            var callerType = callerMethod.DeclaringType;
                            var frame = (stackTrace.FrameCount > 1 ? stackTrace.FrameCount - 1 : 1);
                            stackFrame = stackTrace.GetFrame(frame);
                            var originalCallerMethod = stackFrame.GetMethod();
                            var originalCallerType = originalCallerMethod.DeclaringType;
                            var innerExceptionMessage = string.Format
                                    (
                                        "Rethrow caught [{1}] Exception{0} at Callee Method: [{2}]{0} at Caller Method: [{3}]{0} at Original Caller Method: [{4}]"
                                        , "
    	"
                                        , e.Message
                                        , string.Format("{1}{0}{2}", "::", currentCalleeType, currentCalleeMethod)
                                        , string.Format("{1}{0}{2}", "::", callerType, callerMethod)
                                        , string.Format("{1}{0}{2}", "::", originalCallerType, originalCallerMethod)
                                    );
                            Console.WriteLine(innerExceptionMessage);
                            if (onCaughtExceptionProcessFunc != null)
                            {
                                reThrowException = onCaughtExceptionProcessFunc(e);
                            }
                            if (reThrowException)
                            {
                                throw
                                    new Exception
                                            (
                                                innerExceptionMessage
                                                , e
                                            );
                            }
                            return r;
                        }
                        finally
                        {
                            if (onFinallyProcessAction != null)
                            {
                                onFinallyProcessAction(caughtException, exception);
                            }
                        }
                    }
                    else
                    {
                        return await onTryProcessFunc();
                    }
                }
            }
    //#if NET45
    #endif
            public static void TryProcessCatchFinally
                                        (
                                            bool needTry
                                            , Action onTryProcessAction
                                            , bool reThrowException = false
                                            , Func<Exception, string, bool> onCaughtExceptionProcessFunc = null
                                            , Action<bool, Exception> onFinallyProcessAction = null
                                        )
            {
                if (onTryProcessAction != null)
                {
                    if (needTry)
                    {
                        Exception exception = null;
                        var caughtException = false;
                        try
                        {
                            onTryProcessAction();
                        }
                        catch (Exception e)
                        {
                            caughtException = true;
                            exception = e;
    #if NET45
                            if (e is AggregateException)
                            { 
                                var aggregateException = e as AggregateException;
                                if (aggregateException != null)
                                {
                                    exception = aggregateException.Flatten();
                                }
                            }
    #endif
                            var currentCalleeMethod = MethodInfo.GetCurrentMethod();
                            var currentCalleeType = currentCalleeMethod.DeclaringType;
                            StackTrace stackTrace = new StackTrace(e, true);
                            StackFrame stackFrame = stackTrace.GetFrame(1);
                            var callerMethod = stackFrame.GetMethod();
                            var callerType = callerMethod.DeclaringType;
                            var frame = (stackTrace.FrameCount > 1 ? stackTrace.FrameCount - 1 : 1);
                            stackFrame = stackTrace.GetFrame(frame);
                            var originalCallerMethod = stackFrame.GetMethod();
                            var originalCallerType = originalCallerMethod.DeclaringType;
                            var innerExceptionMessage = string.Format
                                    (
                                        "Rethrow caught [{1}] Exception{0} at Callee Method: [{2}]{0} at Caller Method: [{3}]{0} at Original Caller Method: [{4}]"
                                        , "
    	"
                                        , e.Message
                                        , string.Format("{1}{0}{2}", "::", currentCalleeType, currentCalleeMethod)
                                        , string.Format("{1}{0}{2}", "::", callerType, callerMethod)
                                        , string.Format("{1}{0}{2}", "::", originalCallerType, originalCallerMethod)
                                    );
                            //Console.WriteLine(innerExceptionMessage);
                            if (onCaughtExceptionProcessFunc != null)
                            {
                                reThrowException = onCaughtExceptionProcessFunc(e, innerExceptionMessage);
                            }
                            if (reThrowException)
                            {
                                throw
                                    new Exception
                                            (
                                                innerExceptionMessage
                                                , e
                                            );
                            }
                        }
                        finally
                        {
                            //Console.WriteLine("Finally");
                            if (onFinallyProcessAction != null)
                            {
                                onFinallyProcessAction(caughtException, exception);
                            }
                        }
                    }
                    else
                    {
                        onTryProcessAction();
                    }
                }
            }
        }
    }
    namespace Microshaoft
    {
        using System;
        using System.Linq;
        using System.Linq.Expressions;
        using System.Reflection;
        public class DynamicPropertyAccessor
        {
            private static Assembly GetAssemblyByTypeName(string typeName)
            {
                return
                    AppDomain
                        .CurrentDomain
                            .GetAssemblies()
                                .First
                                    (
                                        (a) =>
                                        {
                                            return
                                                a
                                                    .GetTypes()
                                                        .Any
                                                            (
                                                                (t) =>
                                                                {
                                                                    return
                                                                        (
                                                                            t.FullName
                                                                            == typeName
                                                                        );
                                                                }
                                                            );
                                        }
                                    );
            }
            public static Func<object, object> CreateGetPropertyValueFunc
                            (
                                string typeName
                                , string propertyName
                                , bool isTypeFromAssembly = false
                            )
            {
                Type type;
                if (isTypeFromAssembly)
                {
                    var assembly = GetAssemblyByTypeName(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), "P");
                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 = GetAssemblyByTypeName(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), "p");
                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<TTarget, TProperty> CreateGetPropertyValueFunc<TTarget, TProperty>
                    (
                        Type type
                        , string propertyName
                    )
            {
                var target = Expression.Parameter(typeof(object), "p");
                var getPropertyValue = Expression.Property(target, propertyName);
                var lambda = Expression.Lambda<Func<TTarget, 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 = GetAssemblyByTypeName(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
                            )
            {
                Func<TProperty> func = null;
                var property = type.GetProperty(propertyName, typeof(TProperty));
                if (property == null)
                {
                    property =
                                type
                                    .GetProperties()
                                        .ToList()
                                            .FirstOrDefault
                                                (
                                                    (x) =>
                                                    {
                                                        return
                                                            (
                                                                x.Name.ToLower()
                                                                == propertyName.ToLower()
                                                            );
                                                    }
                                                );
                }
                if (property != null)
                {
                    var getPropertyValue = Expression.Property(null, property);
                    var lambda = Expression.Lambda<Func<TProperty>>(getPropertyValue, null);
                    func = lambda.Compile();
                }
                return func;
            }
            public static Func<object> CreateGetStaticPropertyValueFunc
                            (
                                Type type
                                , string propertyName
                            )
            {
                Func<object> func = null;
                var property = type.GetProperty(propertyName);
                if (property == null)
                {
                    property =
                                type
                                    .GetProperties()
                                        .ToList()
                                            .FirstOrDefault
                                                (
                                                    (x) =>
                                                    {
                                                        return
                                                            (
                                                                x.Name.ToLower()
                                                                == propertyName.ToLower()
                                                            );
                                                    }
                                                );
                }
                if (property != null)
                {
                    var getPropertyValue = Expression.Property(null, property);
                    var castPropertyValue = Expression.Convert(getPropertyValue, typeof(object));
                    var lambda = Expression.Lambda<Func<object>>(castPropertyValue, null);
                    func = lambda.Compile();
                }
                return func;
            }
            public static Func<object> CreateGetStaticPropertyValueFunc
                            (
                                string typeName
                                , string propertyName
                                , bool isTypeFromAssembly = false
                            )
            {
                Type type;
                if (isTypeFromAssembly)
                {
                    var assembly = GetAssemblyByTypeName(typeName);
                    type = assembly.GetType(typeName);
                }
                else
                {
                    type = Type.GetType(typeName);
                }
                return CreateGetStaticPropertyValueFunc(type, propertyName);
            }
            public static Action<object, object> CreateSetPropertyValueAction
                            (
                                Type type
                                , string propertyName
                            )
            {
                Action<object, object> action = null;
                var property = type.GetProperty(propertyName);
                if (property == null)
                {
                    property =
                                type
                                    .GetProperties()
                                        .ToList()
                                            .FirstOrDefault
                                                (
                                                    (x) =>
                                                    {
                                                        return
                                                            (
                                                                x.Name.ToLower()
                                                                == propertyName.ToLower()
                                                            );
                                                    }
                                                );
                }
                if (property != null)
                {
                    var target = Expression.Parameter(typeof(object), "p");
                    var propertyValue = Expression.Parameter(typeof(object), "p");
                    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);
                    action = lambda.Compile();
                }
                return action;
            }
            public static Action<object, object> CreateSetPropertyValueAction
                            (
                                string typeName
                                , string propertyName
                                , bool isTypeFromAssembly = false
                            )
            {
                Type type;
                if (isTypeFromAssembly)
                {
                    var assembly = GetAssemblyByTypeName(typeName);
                    type = assembly.GetType(typeName);
                }
                else
                {
                    type = Type.GetType(typeName);
                }
                return CreateSetPropertyValueAction(type, propertyName);
            }
            public static Action<TTarget, TProperty> CreateTargetSetPropertyValueAction<TTarget, TProperty>
                            (
                                Type type
                                , string propertyName
                            )
            {
                Action<TTarget, TProperty> action = null;
                var property = type.GetProperty(propertyName);
                if (property == null)
                {
                    property =
                                type
                                    .GetProperties()
                                        .ToList()
                                            .FirstOrDefault
                                                (
                                                    (x) =>
                                                    {
                                                        return
                                                            (
                                                                x.Name.ToLower()
                                                                == propertyName.ToLower()
                                                            );
                                                    }
                                                );
                }
                if (property != null)
                {
                    var target = Expression.Parameter(typeof(TTarget), "p");
                    var propertyValue = Expression.Parameter(typeof(TProperty), "p");
                    var getSetMethod = property.GetSetMethod();
                    if (getSetMethod == null)
                    {
                        getSetMethod = property.GetSetMethod(true);
                    }
                    var call = Expression.Call(target, getSetMethod, propertyValue);
                    var lambda = Expression.Lambda<Action<TTarget, TProperty>>(call, target, propertyValue);
                    action = lambda.Compile();
                }
                return action;
            }
            public static Action<TTarget, object> CreateTargetSetPropertyValueAction<TTarget>
                    (
                        Type type
                        , string propertyName
                    )
            {
                Action<TTarget, object> action = null;
                var property = type.GetProperty(propertyName);
                if (property == null)
                {
                    property =
                                type
                                    .GetProperties()
                                        .ToList()
                                            .FirstOrDefault
                                                (
                                                    (x) =>
                                                    {
                                                        return
                                                            (
                                                                x.Name.ToLower()
                                                                == propertyName.ToLower()
                                                            );
                                                    }
                                                );
                }
                if (property != null)
                {
                    var target = Expression.Parameter(typeof(TTarget), "p");
                    var propertyValue = Expression.Parameter(typeof(object), "p");
                    var castPropertyValue = Expression.Convert(propertyValue, property.PropertyType);
                    var getSetMethod = property.GetSetMethod();
                    if (getSetMethod == null)
                    {
                        getSetMethod = property.GetSetMethod(true);
                    }
                    var call = Expression.Call(target, getSetMethod, castPropertyValue);
                    var lambda = Expression.Lambda<Action<TTarget, object>>(call, target, propertyValue);
                    action = lambda.Compile();
                }
                return action;
            }
            public static Action<object, TProperty> CreateSetPropertyValueAction<TProperty>
                    (
                        Type type
                        , string propertyName
                    )
            {
                Action<object, TProperty> action = null;
                var property = type.GetProperty(propertyName);
                if (property == null)
                {
                    property =
                                type
                                    .GetProperties()
                                        .ToList()
                                            .FirstOrDefault
                                                (
                                                    (x) =>
                                                    {
                                                        return
                                                            (
                                                                x.Name.ToLower()
                                                                == propertyName.ToLower()
                                                            );
                                                    }
                                                );
                }
                if (property != null)
                {
                    var target = Expression.Parameter(typeof(object), "p");
                    var propertyValue = Expression.Parameter(typeof(TProperty), "p");
                    var castTarget = Expression.Convert(target, type);
                    var getSetMethod = property.GetSetMethod();
                    if (getSetMethod == null)
                    {
                        getSetMethod = property.GetSetMethod(true);
                    }
                    var call = Expression.Call(castTarget, getSetMethod, propertyValue);
                    var lambda = Expression.Lambda<Action<object, TProperty>>(call, target, propertyValue);
                    action = lambda.Compile();
                }
                return action;
            }
            public static Action<object, TProperty> CreateSetPropertyValueAction<TProperty>
                            (
                                string typeName
                                , string propertyName
                                , bool isTypeFromAssembly = false
                            )
            {
                Type type;
                if (isTypeFromAssembly)
                {
                    var assembly = GetAssemblyByTypeName(typeName);
                    type = assembly.GetType(typeName);
                }
                else
                {
                    type = Type.GetType(typeName);
                }
                return CreateSetPropertyValueAction<TProperty>(type, propertyName);
            }
            public static Action<object> CreateSetStaticPropertyValueAction
                            (
                                Type type
                                , string propertyName
                            )
            {
                Action<object> action = null;
                var property = type.GetProperty(propertyName);
                if (property == null)
                {
                    property =
                                type
                                    .GetProperties()
                                        .ToList()
                                            .FirstOrDefault
                                                (
                                                    (x) =>
                                                    {
                                                        return
                                                            (
                                                                x.Name.ToLower()
                                                                == propertyName.ToLower()
                                                            );
                                                    }
                                                );
                }
                if (property != null)
                {
                    var propertyValue = Expression.Parameter(typeof(object), "p");
                    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);
                    action = lambda.Compile();
                }
                return action;
            }
            public static Action<object> CreateSetStaticPropertyValueAction
                            (
                                string typeName
                                , string propertyName
                                , bool isTypeFromAssembly = false
                            )
            {
                Type type;
                if (isTypeFromAssembly)
                {
                    var assembly = GetAssemblyByTypeName(typeName);
                    type = assembly.GetType(typeName);
                }
                else
                {
                    type = Type.GetType(typeName);
                }
                return CreateSetStaticPropertyValueAction(type, propertyName);
            }
            public static Action<TProperty> CreateSetStaticPropertyValueAction<TProperty>
                            (
                                Type type
                                , string propertyName
                            )
            {
                Action<TProperty> action = null;
                var property = type.GetProperty(propertyName);
                if (property == null)
                {
                    property =
                                type
                                    .GetProperties()
                                        .ToList()
                                            .FirstOrDefault
                                                (
                                                    (x) =>
                                                    {
                                                        return
                                                            (
                                                                x.Name.ToLower()
                                                                == propertyName.ToLower()
                                                            );
                                                    }
                                                );
                }
                if (property != null)
                {
                    var propertyValue = Expression.Parameter(typeof(TProperty), "p");
                    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);
                    action = lambda.Compile();
                }
                return action;
            }
            public static Action<TProperty> CreateSetStaticPropertyValueAction<TProperty>
                            (
                                string typeName
                                , string propertyName
                                , bool isTypeFromAssembly = false
                            )
            {
                Type type;
                if (isTypeFromAssembly)
                {
                    var assembly = GetAssemblyByTypeName(typeName);
                    type = assembly.GetType(typeName);
                }
                else
                {
                    type = Type.GetType(typeName);
                }
                return CreateSetStaticPropertyValueAction<TProperty>(type, propertyName);
            }
        }
    }
    
    
  • 相关阅读:
    纽约顶级富婆鄙视链:4星|《我是个妈妈,我需要铂金包:一个耶鲁人类学博士的上东区育儿战争》
    2星|陈春花《顺德40年》:各种官宣的汇编,内容太虚,新信息太少
    人们喜欢传播符合自己三观的新闻,不在乎真假:4星|《环球科学》2018年12月号
    营销相关21本书
    5星|《辩论:美国制宪会议记录》:200年前的会议纪要
    3星|《品牌物理学》:理论没有实际应用案例,有推销软件的嫌疑
    关于思考的思考12本书,5星2本,4星7本
    Chrome插件 postman的使用方法详解!最全面的教程
    postman发送json请求,使用案例
    SUSE Enterprise Server 12 SP3 64 设置防火墙开放8080端口
  • 原文地址:https://www.cnblogs.com/Microshaoft/p/3960959.html
Copyright © 2020-2023  润新知