/* PowerShell: [System.Diagnostics.PerformanceCounterCategory]::Delete("Microshaoft ConcurrentAsyncQueue Performance Counters") [System.Diagnostics.PerformanceCounterCategory]::GetCategories() | Format-Table -auto [System.Diagnostics.PerformanceCounterCategory]::GetCategories() | Where {$_.CategoryName -like "*microshaoft*" } | Format-Table -auto [Diagnostics.PerformanceCounterCategory]::Delete( "Your Category Name" ) [Diagnostics.PerformanceCounterCategory]::GetCategories() | Format-Table -auto [Diagnostics.PerformanceCounterCategory]::GetCategories() | Where {$_.CategoryName -like "*microshaoft*" } | Format-Table -auto [Diagnostics.PerformanceCounterCategory]::GetCategories() | Where {$_.CategoryName -like "*network*" } | Format-Table -auto [Diagnostics.PerformanceCounterCategory]::GetCategories() | Where {$_.CategoryName -match "SQL.*Stat.*" } | Format-Table -auto $categoryName = "Microshaoft ConcurrentAsyncQueue Performance Counters" $counterName = "" $instanceName = "" if ([System.Diagnostics.PerformanceCounterCategory]::Exists($categoryName)) { #if ([System.Diagnostics.PerformanceCounterCategory]::CounterExists($counterName,$categoryName)) { } if ([System.Diagnostics.PerformanceCounterCategory]::InstanceExists($instanceName, $categoryName)) { $pc = New-Object [System.Diagnostics.PerformanceCounter] ($categoryName, $counterName, $instanceName) $pc.RemoveInstance() [System.Console]::WriteLine("RemoveInstance") } [System.Diagnostics.PerformanceCounterCategory]::Delete($categoryName) [System.Console]::WriteLine("Delete") } */ namespace Test { using Microshaoft; using System; using System.Threading; using System.Threading.Tasks; 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; //Console.WriteLine(sleep); Thread.Sleep(sleep); if (sleep > 400) { Console.WriteLine(x); } } ); q.OnCaughtException += //new ConcurrentAsyncQueue<int>.ExceptionEventHandler ( (x, y) => { Console.WriteLine(y.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(20); } else { Console.WriteLine("please input Number!"); } } } } } namespace Microshaoft { using System; using System.Collections.Concurrent; using System.Diagnostics; using System.Threading; public class ConcurrentAsyncQueue<T> { public delegate void QueueEventHandler(T item); public event QueueEventHandler OnDequeue; public delegate void QueueLogEventHandler(string logMessage); public QueueLogEventHandler OnQueueLog , OnDequeueThreadStart , OnDequeueThreadEnd; public delegate bool ExceptionEventHandler(ConcurrentAsyncQueue<T> sender, Exception exception); public event ExceptionEventHandler OnCaughtException; private ConcurrentQueue<Tuple<Stopwatch, T>> _queue = new ConcurrentQueue<Tuple<Stopwatch, T>>(); 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._queue; var reThrowException = false; PerformanceCountersHelper .TryCountPerformance ( counterEnabled , reThrowException , //IncrementCountersBeforeCountPerformance: new PerformanceCounter[] { qpcc .DequeueThreadStartPerformanceCounter , qpcc .DequeueThreadsCountPerformanceCounter } , //DecrementCountersBeforeCountPerformance: 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)) { PerformanceCountersHelper .TryCountPerformance ( counterEnabled , reThrowException , new PerformanceCounter[] { qpcc .DequeuePerformanceCounter } , new PerformanceCounter[] { qpcc .QueueLengthPerformanceCounter } , 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 , new Stopwatch() , qpcc .DequeueProcessedAverageTimerPerformanceCounter , qpcc .DequeueProcessedAverageBasePerformanceCounter ) } , () => //try { if (Sender.OnDequeue != null) { var element = item.Item2; item = null; Sender.OnDequeue(element); } } , (x) => //catch { reThrowException = false; return reThrowException; } , null //finally , null , new PerformanceCounter[] { qpcc .DequeueProcessedPerformanceCounter , qpcc .DequeueProcessedRateOfCountsPerSecondPerformanceCounter } ); } #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._queue.Count , Thread.CurrentThread.Name , DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fffff") ) ); } if (!Break) { Sender.StartIncreaseDequeueProcessThreads(1); } Break = false; #endregion } , //DecrementCountersAfterCountPerformance: new PerformanceCounter[] { qpcc.DequeueThreadsCountPerformanceCounter } , //IncrementCountersAfterCountPerformance: new PerformanceCounter[] { qpcc.DequeueThreadEndPerformanceCounter } ); } } 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; PerformanceCountersHelper .TryCountPerformance ( enableCount , reThrowException , new PerformanceCounter[] { PerformanceCounters .EnqueuePerformanceCounter , PerformanceCounters .EnqueueRateOfCountsPerSecondPerformanceCounter , PerformanceCounters .QueueLengthPerformanceCounter } , null , null , () => { Stopwatch stopwatch = null; if (_isAttachedPerformanceCounters) { 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 { #region PerformanceCounters private PerformanceCounter _enqueuePerformanceCounter; [ PerformanceCounterDefinitionAttribute ( CounterType = PerformanceCounterType.NumberOfItems64 , CounterName = "01.入队列累计总数(笔)" ) ] public PerformanceCounter EnqueuePerformanceCounter { private set { ReaderWriterLockSlimHelper .TryEnterWriterLockSlimWrite<PerformanceCounter> (ref _enqueuePerformanceCounter, value, 2); } get { return _enqueuePerformanceCounter; } } private PerformanceCounter _enqueueRateOfCountsPerSecondPerformanceCounter; [ PerformanceCounterDefinitionAttribute ( CounterType = PerformanceCounterType.RateOfCountsPerSecond64 , CounterName = "02.每秒入队列笔数(笔/秒)" ) ] public PerformanceCounter EnqueueRateOfCountsPerSecondPerformanceCounter { private set { ReaderWriterLockSlimHelper .TryEnterWriterLockSlimWrite<PerformanceCounter> (ref _enqueueRateOfCountsPerSecondPerformanceCounter, value, 2); } get { return _enqueueRateOfCountsPerSecondPerformanceCounter; } } private PerformanceCounter _queueLengthPerformanceCounter; [ PerformanceCounterDefinitionAttribute ( CounterType = PerformanceCounterType.NumberOfItems64 , CounterName = "03.队列当前长度(笔)" ) ] public PerformanceCounter QueueLengthPerformanceCounter { private set { ReaderWriterLockSlimHelper .TryEnterWriterLockSlimWrite<PerformanceCounter> (ref _queueLengthPerformanceCounter, value, 2); } get { return _queueLengthPerformanceCounter; } } private PerformanceCounter _dequeuePerformanceCounter; [ PerformanceCounterDefinitionAttribute ( CounterType = PerformanceCounterType.NumberOfItems64 , CounterName = "04.出队列累计总数(笔)" ) ] public PerformanceCounter DequeuePerformanceCounter { private set { ReaderWriterLockSlimHelper .TryEnterWriterLockSlimWrite<PerformanceCounter> (ref _dequeuePerformanceCounter, value, 2); } get { return _dequeuePerformanceCounter; } } private PerformanceCounter _dequeueProcessedRateOfCountsPerSecondPerformanceCounter; [ PerformanceCounterDefinitionAttribute ( CounterType = PerformanceCounterType.RateOfCountsPerSecond64 , CounterName = "05.每秒出队列并完成处理笔数(笔/秒)" ) ] public PerformanceCounter DequeueProcessedRateOfCountsPerSecondPerformanceCounter { private set { ReaderWriterLockSlimHelper .TryEnterWriterLockSlimWrite<PerformanceCounter> (ref _dequeueProcessedRateOfCountsPerSecondPerformanceCounter, value, 2); } get { return _dequeueProcessedRateOfCountsPerSecondPerformanceCounter; } } private PerformanceCounter _dequeueProcessedPerformanceCounter; [ PerformanceCounterDefinitionAttribute ( CounterType = PerformanceCounterType.NumberOfItems64 , CounterName = "06.已出队列并完成处理累计总笔数(笔)" ) ] public PerformanceCounter DequeueProcessedPerformanceCounter { private set { ReaderWriterLockSlimHelper .TryEnterWriterLockSlimWrite<PerformanceCounter> (ref _dequeueProcessedPerformanceCounter, value, 2); } get { return _dequeueProcessedPerformanceCounter; } } private PerformanceCounter _dequeueProcessedAverageTimerPerformanceCounter; [ PerformanceCounterDefinitionAttribute ( CounterType = PerformanceCounterType.AverageTimer32 , CounterName = "07.每笔已出队列并完成处理平均耗时秒数(秒/笔)" ) ] public PerformanceCounter DequeueProcessedAverageTimerPerformanceCounter { private set { ReaderWriterLockSlimHelper .TryEnterWriterLockSlimWrite<PerformanceCounter> (ref _dequeueProcessedAverageTimerPerformanceCounter, value, 2); } get { return _dequeueProcessedAverageTimerPerformanceCounter; } } private PerformanceCounter _dequeueProcessedAverageBasePerformanceCounter; [ PerformanceCounterDefinitionAttribute ( CounterType = PerformanceCounterType.AverageBase ) ] public PerformanceCounter DequeueProcessedAverageBasePerformanceCounter { private set { ReaderWriterLockSlimHelper .TryEnterWriterLockSlimWrite<PerformanceCounter> (ref _dequeueProcessedAverageBasePerformanceCounter, value, 2); } get { return _dequeueProcessedAverageBasePerformanceCounter; } } private PerformanceCounter _queuedWaitAverageTimerPerformanceCounter; [ PerformanceCounterDefinitionAttribute ( CounterType = PerformanceCounterType.AverageTimer32 , CounterName = "08.每笔入出队列并完成处理平均耗时秒数(秒/笔)" ) ] public PerformanceCounter QueuedWaitAverageTimerPerformanceCounter { private set { ReaderWriterLockSlimHelper .TryEnterWriterLockSlimWrite<PerformanceCounter> (ref _queuedWaitAverageTimerPerformanceCounter, value, 2); } get { return _queuedWaitAverageTimerPerformanceCounter; } } private PerformanceCounter _queuedWaitAverageBasePerformanceCounter; [ PerformanceCounterDefinitionAttribute ( CounterType = PerformanceCounterType.AverageBase ) ] public PerformanceCounter QueuedWaitAverageBasePerformanceCounter { private set { ReaderWriterLockSlimHelper .TryEnterWriterLockSlimWrite<PerformanceCounter> (ref _queuedWaitAverageBasePerformanceCounter, value, 2); } get { return _queuedWaitAverageBasePerformanceCounter; } } private PerformanceCounter _dequeueThreadStartPerformanceCounter; [ PerformanceCounterDefinitionAttribute ( CounterType = PerformanceCounterType.NumberOfItems64 , CounterName = "09.新建出队列处理线程启动次数(次)" ) ] public PerformanceCounter DequeueThreadStartPerformanceCounter { private set { ReaderWriterLockSlimHelper .TryEnterWriterLockSlimWrite<PerformanceCounter> (ref _dequeueThreadStartPerformanceCounter, value, 2); } get { return _dequeueThreadStartPerformanceCounter; } } private PerformanceCounter _dequeueThreadsCountPerformanceCounter; [ PerformanceCounterDefinitionAttribute ( CounterType = PerformanceCounterType.NumberOfItems64 , CounterName = "10.当前出队列并发处理线程数(个)" ) ] public PerformanceCounter DequeueThreadsCountPerformanceCounter { private set { ReaderWriterLockSlimHelper .TryEnterWriterLockSlimWrite<PerformanceCounter> (ref _dequeueThreadsCountPerformanceCounter, value, 2); } get { return _dequeueThreadsCountPerformanceCounter; } } private PerformanceCounter _dequeueThreadEndPerformanceCounter; [ PerformanceCounterDefinitionAttribute ( CounterType = PerformanceCounterType.NumberOfItems64 , CounterName = "11.出队列处理线程退出次数(次)" ) ] public PerformanceCounter DequeueThreadEndPerformanceCounter { private set { ReaderWriterLockSlimHelper .TryEnterWriterLockSlimWrite<PerformanceCounter> (ref _dequeueThreadEndPerformanceCounter, value, 2); } 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; using System.Diagnostics; [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 ) { x.Item2.Start(); } } ); } #endregion } var needTry = true; TryCatchFinallyProcessHelper .TryProcessCatchFinally ( needTry , () => { onTryCountPerformanceProcessAction(); } , reThrowException , (x) => { if (onCaughtExceptionCountPerformanceProcessFunc != null) { reThrowException = onCaughtExceptionCountPerformanceProcessFunc(x); } return reThrowException; } , (x, y) => { if (enableCount) { #region after 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(); } } ); } 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.Threading; public static class ReaderWriterLockSlimHelper { public static bool TryEnterWriterLockSlimWrite<T> ( ref T target , T newTarget , int enterTimeOutSeconds ) where T : class { bool r = false; var rwls = new ReaderWriterLockSlim(); int timeOut = Timeout.Infinite; if (enterTimeOutSeconds >= 0) { timeOut = enterTimeOutSeconds * 1000; } try { r = (rwls.TryEnterWriteLock(timeOut)); if (r) { Interlocked.Exchange<T>(ref target, newTarget); r = true; } } finally { if (r) { rwls.ExitWriteLock(); } } return r; } public static bool TryEnterWriterLockSlim ( Action action , int enterTimeOutSeconds ) { bool r = false; if (action != null) { var rwls = new ReaderWriterLockSlim(); int timeOut = Timeout.Infinite; if (enterTimeOutSeconds >= 0) { timeOut = enterTimeOutSeconds * 1000; } try { r = (rwls.TryEnterWriteLock(timeOut)); if (r) { action(); r = true; } } finally { if (r) { rwls.ExitWriteLock(); } } } return r; } } } namespace Microshaoft { using System; using System.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)); 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)); var castTarget = Expression.Convert(target, type); var getPropertyValue = Expression.Property(castTarget, propertyName); var lambda = Expression.Lambda<Func<object, TProperty>>(getPropertyValue, target); return lambda.Compile(); } public static Func<TProperty> CreateGetStaticPropertyValueFunc<TProperty> ( string typeName , string propertyName , bool isTypeFromAssembly = false ) { Type type; if (isTypeFromAssembly) { var assembly = 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)); var propertyValue = Expression.Parameter(typeof(object)); var castTarget = Expression.Convert(target, type); var castPropertyValue = Expression.Convert(propertyValue, property.PropertyType); var getSetMethod = property.GetSetMethod(); if (getSetMethod == null) { getSetMethod = property.GetSetMethod(true); } var call = Expression.Call(castTarget, getSetMethod, castPropertyValue); var lambda = Expression.Lambda<Action<object, object>>(call, target, propertyValue); 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<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)); var propertyValue = Expression.Parameter(typeof(TProperty)); var castTarget = Expression.Convert(target, type); var castPropertyValue = Expression.Convert(propertyValue, property.PropertyType); var getSetMethod = property.GetSetMethod(); if (getSetMethod == null) { getSetMethod = property.GetSetMethod(true); } var call = Expression.Call(castTarget, getSetMethod, castPropertyValue); 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)); 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)); //var castPropertyValue = Expression.Convert(propertyValue, property.PropertyType); var getSetMethod = property.GetSetMethod(); if (getSetMethod == null) { getSetMethod = property.GetSetMethod(true); } var call = Expression.Call(null, getSetMethod, propertyValue); var lambda = Expression.Lambda<Action<TProperty>>(call, propertyValue); 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); } } } 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.Diagnostics; using System.Reflection; using System.Threading.Tasks; public static class TryCatchFinallyProcessHelper { 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; if (onCaughtExceptionProcessFunc != null) { reThrowException = onCaughtExceptionProcessFunc(e); } if (reThrowException) { var currentCalleeMethod = MethodInfo.GetCurrentMethod(); var currentCalleeType = currentCalleeMethod.DeclaringType; StackTrace stackTrace = new StackTrace(); var callerMethod = stackTrace.GetFrame(1).GetMethod(); var callerType = callerMethod.DeclaringType; var innerExceptionMessage = string.Format ( "[{1}]{0}Caught Exception in Caller's [{2}]{0}Rethrow Exception on [{3}]" , "\r\n\t" , string.Format("{1}{0}{2}", "::", currentCalleeType, currentCalleeMethod) , string.Format("{1}{0}{2}", "::", callerType, callerMethod) , "Catch Exception" ); throw new Exception ( innerExceptionMessage , e ); } return r; } finally { if (onFinallyProcessAction != null) { onFinallyProcessAction(caughtException, exception); } } } else { return await onTryProcessFunc(); } } } public static void TryProcessCatchFinally ( bool needTry , Action onTryProcessAction , bool reThrowException = false , Func<Exception, 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 (onCaughtExceptionProcessFunc != null) { reThrowException = onCaughtExceptionProcessFunc(e); } if (reThrowException) { var currentCalleeMethod = MethodInfo.GetCurrentMethod(); var currentCalleeType = currentCalleeMethod.DeclaringType; StackTrace stackTrace = new StackTrace(); var callerMethod = stackTrace.GetFrame(1).GetMethod(); var callerType = callerMethod.DeclaringType; var innerExceptionMessage = string.Format ( "[{1}]{0}Caught Exception in Caller's [{2}]{0}Rethrow Exception on [{3}]" , "\r\n\t" , string.Format("{1}{0}{2}", "::", currentCalleeType, currentCalleeMethod) , string.Format("{1}{0}{2}", "::", callerType, callerMethod) , "Catch Exception" ); throw new Exception ( innerExceptionMessage , e ); } } finally { if (onFinallyProcessAction != null) { onFinallyProcessAction(caughtException, exception); } } } else { onTryProcessAction(); } } } } } |