并发异步处理队列 .NET 4.5+
2013-06-22 20:25
162 查看
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; //Console.WriteLine(sleep); //Thread.Sleep(sleep); if (sleep > 400) { Console.WriteLine(x); } } ); q.OnException += new ConcurrentAsyncQueue<int> .ExceptionEventHandler ( (x) => { Console.WriteLine(x.ToString()); } ); Console.WriteLine("begin ..."); //q.StartAdd(10); string r = string.Empty; while ((r = Console.ReadLine()) != "q") { int i; if (int.TryParse(r, out i)) { Console.WriteLine("Parallel Enqueue {0} begin ...", i); new Thread ( new ParameterizedThreadStart ( (x) => { Parallel .For ( 0 , i , (xx) => { q.Enqueue(xx); } ); Console.WriteLine("Parallel Enqueue {0} end ...", i); } ) ).Start(); } else if (r.ToLower() == "stop") { q.StartStop(10); } else if (r.ToLower() == "add") { q.StartAdd(20); } else { Console.WriteLine("please input Number!"); } } } } } namespace Microshaoft { using System; using System.Collections.Concurrent; using System.Diagnostics; using System.Threading; public class ConcurrentAsyncQueue<T> { public delegate void QueueEventHandler(T item); public event QueueEventHandler OnDequeue; public delegate void QueueLogEventHandler(string logMessage); public QueueLogEventHandler OnQueueLog , OnDequeueThreadStart , OnDequeueThreadEnd; public delegate void ExceptionEventHandler(Exception exception); public event ExceptionEventHandler OnException; private ConcurrentQueue<Tuple<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() { Interlocked.Increment(ref Sender._concurrentDequeueThreadsCount); bool counterEnabled = Sender._isAttachedPerformanceCounters; if (counterEnabled) { Sender .PerformanceCounters .DequeueThreadStartPerformanceCounter .ChangeCounterValueWithTryCatchExceptionFinally<long> ( counterEnabled , (x) => { return x.Increment(); } ); Sender .PerformanceCounters .DequeueThreadsCountPerformanceCounter .Increment(); } long r = 0; try { if (Sender.OnDequeueThreadStart != null) { r = Interlocked.Read(ref Sender._concurrentDequeueThreadsCount); Sender.OnDequeueThreadStart ( string .Format ( "{0} Threads Count {1},Queue Count {2},Current Thread: {3} at {4}" , "Threads ++ !" , r , Sender._queue.Count , Thread.CurrentThread.Name , DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fffff") ) ); } while (true) { #region while true loop if (Break) { break; } while (!Sender._queue.IsEmpty) { #region while queue.IsEmpty loop if (Break) { break; } Tuple<Stopwatch, T> item = null; if (Sender._queue.TryDequeue(out item)) { if (counterEnabled) { Sender.PerformanceCounters.DequeuePerformanceCounter.Increment(); Sender.PerformanceCounters.QueueLengthPerformanceCounter.Decrement(); } if (Sender.OnDequeue != null) { if (counterEnabled) { var beginTimeStopwatch = item.Item1; if ( beginTimeStopwatch != null ) { beginTimeStopwatch.Stop(); long elapsedTicks = beginTimeStopwatch.ElapsedTicks; Sender .PerformanceCounters .QueuedWaitAverageTimerPerformanceCounter .IncrementBy(elapsedTicks); Sender .PerformanceCounters .QueuedWaitAverageBasePerformanceCounter .Increment(); } } var element = item.Item2; item = null; Sender .PerformanceCounters .DequeueProcessedAverageTimerPerformanceCounter .ChangeAverageTimerCounterValueWithTryCatchExceptionFinally ( counterEnabled , Sender.PerformanceCounters.DequeueProcessedAverageBasePerformanceCounter , () => { Sender.OnDequeue(element); } ); } if (Sender._isAttachedPerformanceCounters) { Sender .PerformanceCounters .DequeueProcessedPerformanceCounter .Increment(); Sender .PerformanceCounters .DequeueProcessedRateOfCountsPerSecondPerformanceCounter .Increment(); } } #endregion while queue.IsEmpty loop } #region wait Sender._dequeueThreadsProcessorsPool.Enqueue(this); if (Break) { } if (!Wait.WaitOne(Sender.DequeueIdleSleepSeconds * 1000)) { } #endregion wait #endregion while true loop } } catch (Exception e) { if (Sender.OnException != null) { Sender.OnException(e); } } finally { r = Interlocked.Decrement(ref Sender._concurrentDequeueThreadsCount); if (r < 0) { Interlocked.Exchange(ref Sender._concurrentDequeueThreadsCount, 0); if (Sender._isAttachedPerformanceCounters) { if ( Sender .PerformanceCounters .DequeueThreadsCountPerformanceCounter .RawValue < 0 ) { Sender .PerformanceCounters .DequeueThreadsCountPerformanceCounter .RawValue = Sender._concurrentDequeueThreadsCount; } } } if (Sender.OnDequeueThreadEnd != null) { Sender.OnDequeueThreadEnd ( string .Format ( "{0} Threads Count {1},Queue Count {2},Current Thread: {3} at {4}" , "Threads--" , r , Sender._queue.Count , Thread.CurrentThread.Name , DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fffff") ) ); } if (Sender._isAttachedPerformanceCounters) { Sender .PerformanceCounters .DequeueThreadEndPerformanceCounter .Increment(); Sender .PerformanceCounters .DequeueThreadsCountPerformanceCounter .Decrement(); } if (!Break) { Sender.StartAdd(1); } Break = false; } } } public void AttachPerformanceCounters ( string instanceNamePrefix , string categoryName , 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 Stop(int count) { Action action; for (var i = 0; i < count; i++) { if (_callbackProcessBreaksActions.TryDequeue(out action)) { action(); action = null; } } } public void StartStop(int count) { new Thread ( new ThreadStart ( () => { Stop(count); } ) ).Start(); } public void StartAdd(int count) { new Thread ( new ThreadStart ( () => { Add(count); } ) ).Start(); } private void Add(int count) { for (int i = 0; i < count; i++) { Interlocked.Increment(ref _concurrentDequeueThreadsCount); if (_dequeueThreadsProcessorsPool == null) { _dequeueThreadsProcessorsPool = new ConcurrentQueue<ThreadProcessor>(); } var processor = new ThreadProcessor ( this , new AutoResetEvent(false) ); var thread = new Thread ( new ThreadStart ( processor.ThreadProcess ) ); if (_callbackProcessBreaksActions == null) { _callbackProcessBreaksActions = new ConcurrentQueue<Action>(); } var callbackProcessBreakAction = new Action ( processor.StopOne ); _callbackProcessBreaksActions.Enqueue(callbackProcessBreakAction); _dequeueThreadsProcessorsPool.Enqueue(processor); thread.Start(); } } public void Enqueue(T item) { try { Stopwatch stopwatch = null; if (_isAttachedPerformanceCounters) { stopwatch = Stopwatch.StartNew(); } var element = Tuple.Create<Stopwatch, T>(stopwatch, item); _queue.Enqueue(element); if (_isAttachedPerformanceCounters) { PerformanceCounters.EnqueuePerformanceCounter.Increment(); PerformanceCounters.EnqueueRateOfCountsPerSecondPerformanceCounter.Increment(); PerformanceCounters.QueueLengthPerformanceCounter.Increment(); } if ( _dequeueThreadsProcessorsPool != null && !_dequeueThreadsProcessorsPool.IsEmpty ) { ThreadProcessor processor; if (_dequeueThreadsProcessorsPool.TryDequeue(out processor)) { processor.Wait.Set(); processor = null; //Console.WriteLine("processor = null;"); } } } catch (Exception e) { if (OnException != null) { OnException(e); } } } } } namespace Microshaoft { using System; using System.Diagnostics; using System.Linq; using System.Collections.Concurrent; public class QueuePerformanceCountersContainer { #region PerformanceCounters private PerformanceCounter _enqueuePerformanceCounter; [PerformanceCounterDefinitionAttribute(CounterType = PerformanceCounterType.NumberOfItems64)] public PerformanceCounter EnqueuePerformanceCounter { private set { ReaderWriterLockSlimHelper .TryEnterWriterLockSlimWrite<PerformanceCounter> ( ref _enqueuePerformanceCounter , value , 2 ); } get { return _enqueuePerformanceCounter; } } private PerformanceCounter _enqueueRateOfCountsPerSecondPerformanceCounter; [ PerformanceCounterDefinitionAttribute ( CounterType = PerformanceCounterType.RateOfCountsPerSecond64 ) ] public PerformanceCounter EnqueueRateOfCountsPerSecondPerformanceCounter { private set { ReaderWriterLockSlimHelper.TryEnterWriterLockSlimWrite<PerformanceCounter>(ref _enqueueRateOfCountsPerSecondPerformanceCounter, value, 2); } get { return _enqueueRateOfCountsPerSecondPerformanceCounter; } } private PerformanceCounter _dequeuePerformanceCounter; [PerformanceCounterDefinitionAttribute(CounterType = PerformanceCounterType.NumberOfItems64)] public PerformanceCounter DequeuePerformanceCounter { private set { ReaderWriterLockSlimHelper .TryEnterWriterLockSlimWrite<PerformanceCounter> ( ref _dequeuePerformanceCounter , value , 2 ); } get { return _dequeuePerformanceCounter; } } private PerformanceCounter _dequeueProcessedRateOfCountsPerSecondPerformanceCounter; [ PerformanceCounterDefinitionAttribute ( CounterType = PerformanceCounterType.RateOfCountsPerSecond64 ) ] public PerformanceCounter DequeueProcessedRateOfCountsPerSecondPerformanceCounter { private set { ReaderWriterLockSlimHelper .TryEnterWriterLockSlimWrite<PerformanceCounter> ( ref _dequeueProcessedRateOfCountsPerSecondPerformanceCounter , value , 2 ); } get { return _dequeueProcessedRateOfCountsPerSecondPerformanceCounter; } } private PerformanceCounter _dequeueProcessedPerformanceCounter; [ PerformanceCounterDefinitionAttribute ( CounterType = PerformanceCounterType.NumberOfItems64 ) ] public PerformanceCounter DequeueProcessedPerformanceCounter { private set { ReaderWriterLockSlimHelper .TryEnterWriterLockSlimWrite<PerformanceCounter> ( ref _dequeueProcessedPerformanceCounter , value , 2 ); } get { return _dequeueProcessedPerformanceCounter; } } private PerformanceCounter _dequeueProcessedAverageTimerPerformanceCounter; [ PerformanceCounterDefinitionAttribute ( CounterType = PerformanceCounterType.AverageTimer32 ) ] 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)] 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 _queueLengthPerformanceCounter; [PerformanceCounterDefinitionAttribute(CounterType = PerformanceCounterType.NumberOfItems64)] public PerformanceCounter QueueLengthPerformanceCounter { private set { ReaderWriterLockSlimHelper .TryEnterWriterLockSlimWrite<PerformanceCounter> ( ref _queueLengthPerformanceCounter , value , 2 ); } get { return _queueLengthPerformanceCounter; } } private PerformanceCounter _dequeueThreadStartPerformanceCounter; [PerformanceCounterDefinitionAttribute(CounterType = PerformanceCounterType.NumberOfItems64)] public PerformanceCounter DequeueThreadStartPerformanceCounter { private set { ReaderWriterLockSlimHelper .TryEnterWriterLockSlimWrite<PerformanceCounter> ( ref _dequeueThreadStartPerformanceCounter , value , 2 ); } get { return _dequeueThreadStartPerformanceCounter; } } private PerformanceCounter _dequeueThreadEndPerformanceCounter; [PerformanceCounterDefinitionAttribute(CounterType = PerformanceCounterType.NumberOfItems64)] public PerformanceCounter DequeueThreadEndPerformanceCounter { private set { ReaderWriterLockSlimHelper .TryEnterWriterLockSlimWrite<PerformanceCounter> ( ref _dequeueThreadEndPerformanceCounter , value , 2 ); } get { return _dequeueThreadEndPerformanceCounter; } } private PerformanceCounter _dequeueThreadsCountPerformanceCounter; [PerformanceCounterDefinitionAttribute(CounterType = PerformanceCounterType.NumberOfItems64)] public PerformanceCounter DequeueThreadsCountPerformanceCounter { private set { ReaderWriterLockSlimHelper .TryEnterWriterLockSlimWrite<PerformanceCounter> ( ref _dequeueThreadsCountPerformanceCounter , value , 2 ); } get { return _dequeueThreadsCountPerformanceCounter; } } #endregion // indexer declaration public PerformanceCounter this[string name] { get { throw new NotImplementedException(); //return null; } } private bool _isAttachedPerformanceCounters = false; public void AttachPerformanceCountersToProperties ( string instanceName , string categoryName ) { if (!_isAttachedPerformanceCounters) { var type = this.GetType(); PerformanceCountersHelper .AttachPerformanceCountersToProperties<QueuePerformanceCountersContainer> ( instanceName , categoryName , this ); } _isAttachedPerformanceCounters = true; } } } namespace Microshaoft { using System; using System.Diagnostics; public static class PerformanceCounterExtensionMethodsManager { public static T ChangeCounterValueWithTryCatchExceptionFinally<T> ( this PerformanceCounter performanceCounter , bool enabled , Func<PerformanceCounter, T> onCounterChangeProcessFunc = null , Action<PerformanceCounter> onCounterChangedProcessAction = null , Func<PerformanceCounter, Exception, bool> onCaughtExceptionProcessFunc = null , Action<PerformanceCounter> onCaughtExceptionFinallyProcessAction = null ) { T r = default(T); if (enabled) { if (onCounterChangeProcessFunc != null) { var caughtException = false; try { r = onCounterChangeProcessFunc(performanceCounter); } catch (Exception e) { caughtException = true; var reThrow = true; if (onCaughtExceptionProcessFunc != null) { reThrow = onCaughtExceptionProcessFunc(performanceCounter, e); } if (reThrow) { throw new Exception("ReThrow Exception On Caught Excepion", e); } } finally { if (caughtException) { if (onCaughtExceptionFinallyProcessAction != null) { onCaughtExceptionFinallyProcessAction(performanceCounter); } } } } } if (onCounterChangedProcessAction != null) { var caughtException = false; try { onCounterChangedProcessAction(performanceCounter); } catch (Exception e) { caughtException = true; var reThrow = true; if (onCaughtExceptionProcessFunc != null) { reThrow = onCaughtExceptionProcessFunc(performanceCounter, e); } if (reThrow) { throw new Exception("ReThrow Exception On Caught Excepion", e); } } finally { if (caughtException) { if (onCaughtExceptionFinallyProcessAction != null) { onCaughtExceptionFinallyProcessAction(performanceCounter); } } } } return r; } public static void ChangeAverageTimerCounterValueWithTryCatchExceptionFinally ( this PerformanceCounter performanceCounter , bool enabled , PerformanceCounter basePerformanceCounter , Action onCountPerformanceInnerProcessAction = null , Func<PerformanceCounter, Exception, bool> onCaughtExceptionProcessFunc = null , Action<PerformanceCounter, PerformanceCounter> onCaughtExceptionFinallyProcessAction = null ) { if (enabled) { var stopwatch = Stopwatch.StartNew(); if (onCountPerformanceInnerProcessAction != null) { var caughtException = false; try { onCountPerformanceInnerProcessAction(); } catch (Exception e) { caughtException = true; var reThrow = true; if (onCaughtExceptionProcessFunc != null) { reThrow = onCaughtExceptionProcessFunc(performanceCounter, e); } if (reThrow) { throw new Exception("ReThrow Exception On Caught Excepion", e); } } finally { stopwatch.Stop(); performanceCounter.IncrementBy(stopwatch.ElapsedTicks); stopwatch = null; basePerformanceCounter.Increment(); if (caughtException) { if (onCaughtExceptionFinallyProcessAction != null) { onCaughtExceptionFinallyProcessAction ( performanceCounter , basePerformanceCounter ); } } } } } } } } //======================================================================================================= //======================================================================================================= 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.Diagnostics; using System.Linq; public static class PerformanceCountersHelper { public static void AttachPerformanceCountersToProperties<T> ( string performanceCounterInstanceName , string category , T target //= default(T) ) { var type = typeof(T); var propertiesList = type.GetProperties().ToList(); propertiesList = propertiesList .Where ( (pi) => { var parameters = pi.GetIndexParameters(); return ( pi.PropertyType == typeof(PerformanceCounter) && (parameters == null ? 0 : parameters.Length) <= 0 ); } ).ToList(); if (PerformanceCounterCategory.Exists(category)) { propertiesList .ForEach ( (pi) => { if (PerformanceCounterCategory.CounterExists(pi.Name, category)) { if (PerformanceCounterCategory.InstanceExists(performanceCounterInstanceName, category)) { //var pc = new PerformanceCounter(category, pi.Name, instanceName, false); //pc.InstanceName = instanceName; //pc.RemoveInstance(); } } } ); //PerformanceCounterCategory.Delete(category); } 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(); } } } |
相关文章推荐
- 并发异步处理队列 .NET 4.5+ (改进性能计数器) 2013-11-16
- .Net 并发异步处理总结
- 【.Net】文件并发(日志处理)--队列--Redis+Log4Net
- 【Java并发编程实战】-----“J.U.C”:CLH队列锁
- Wix安装程序中判断是否安装的.net framwork 4.5
- .NET组件程序设计 第8章 多线程和并发管理
- .NET组件程序设计 第8章 多线程和并发管理 同步线程_监视器
- .NET 4.5 MEF 基于约定的编程模型---重典
- 聊聊并发(七)——Java中的阻塞队列
- 【Java 集合与队列的插入、删除在并发下的性能比较】
- .NET组件程序设计 第8章 多线程和并发管理 .NET多线程服务
- 并发队列-无界非阻塞队列 ConcurrentLinkedQueue 原理探究
- 消息队列在 .NET 中的应用
- Java多线程与并发应用-(10)-java阻塞队列实现ArrayBlockingQueue
- Java多线程 阻塞队列和并发集合
- 并发无锁环形队列的实现
- Windows Identity Foundation已包含在.NET 4.5中
- GCD串行并发队列扫盲
- 【死磕Java并发】—– J.U.C之AQS:CLH同步队列
- .NET 多线程同步 / 并发操作数据唯一