namespace Test { using Microshaoft; using System; using System.Net; using System.Net.Sockets; using System.Text; using System.Threading; using System.Threading.Tasks; class Program { static BufferManager _bufferManager; static SocketAsyncEventArgsPool _socketAsyncEventArgsPool; static void Main(string[] args) { args = new string[] { "127.0.0.1:10080" , "127.0.0.1:10081" }; _bufferManager = new BufferManager ( 64 * 1024 * 1024 , 64 * 1024 ); _bufferManager.InitBuffer(); _socketAsyncEventArgsPool = new SocketAsyncEventArgsPool(100); var performanceCountersCategoryName = "Microshaoft EasyPerformanceCounters Category"; EasyPerformanceCountersHelper<CommonPerformanceCountersContainer> .AttachPerformanceCountersCategoryInstance ( performanceCountersCategoryName , "Hander1::Sended" ); EasyPerformanceCountersHelper<CommonPerformanceCountersContainer> .AttachPerformanceCountersCategoryInstance ( performanceCountersCategoryName , "Hander2::Sended" ); EasyPerformanceCountersHelper<CommonPerformanceCountersContainer> .AttachPerformanceCountersCategoryInstance ( performanceCountersCategoryName , "Hander1::Received" ); EasyPerformanceCountersHelper<CommonPerformanceCountersContainer> .AttachPerformanceCountersCategoryInstance ( performanceCountersCategoryName , "Hander2::Received" ); Console.WriteLine(@"Press any key to Send! Press ""q"" to release resource"); string s = string.Empty; while ((s = Console.ReadLine().ToLower()) != "q") { Run(args); } } static void Run(string[] args) { var performanceCountersCategoryName = "Microshaoft EasyPerformanceCounters Category"; var enableCounters = MultiPerformanceCountersTypeFlags.ProcessCounter | MultiPerformanceCountersTypeFlags.ProcessedAverageTimerCounter | MultiPerformanceCountersTypeFlags.ProcessedCounter | MultiPerformanceCountersTypeFlags.ProcessedRateOfCountsPerSecondCounter | MultiPerformanceCountersTypeFlags.ProcessingCounter; var sendEncoding = Encoding.Default; var receiveEncoding = Encoding.Default; //byte[] data = new byte[1024]; string[] a = args[0].Split(new char[] { ':' }); string ip = a[0]; int port = int.Parse(a[1]); IPEndPoint ipep1 = new IPEndPoint(IPAddress.Parse(ip), port); Console.WriteLine("ipep1 {0}", ipep1.ToString()); a = args[1].Split(new char[] { ':' }); ip = a[0]; port = int.Parse(a[1]); IPEndPoint ipep2 = new IPEndPoint(IPAddress.Parse(ip), port); Console.WriteLine("ipep2 {0}", ipep2.ToString()); var remoteAnyIPEP = new IPEndPoint(IPAddress.Any, 0); Socket socket1 = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); socket1.Bind(ipep1); SocketAsyncDataHandler<string> handler1 = new SocketAsyncDataHandler<string>(socket1, 1); var receiveSocketAsyncEventArgs1 = _socketAsyncEventArgsPool.Pop(); _bufferManager.SetBuffer(receiveSocketAsyncEventArgs1); handler1.StartReceiveDataFrom ( remoteAnyIPEP , receiveSocketAsyncEventArgs1 , (x, y, z) => { Console.WriteLine("次数: {0}", x.ReceivedCount); Console.WriteLine("字节: {0}", y.Length); EasyPerformanceCountersHelper<CommonPerformanceCountersContainer> .CountPerformance ( enableCounters , performanceCountersCategoryName , "Hander1::Received" , null , () => { var ss = receiveEncoding.GetString(y); //Console.Write(s); Console.WriteLine ( "from {0} , to {1}, data {2}" , x.WorkingSocket.LocalEndPoint , z.RemoteEndPoint , ss ); } , null , null , null ); return false; } , (x, y, z) => { Console.WriteLine(z.ToString()); return true; } ); Socket socket2 = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); socket2.Bind(ipep2); SocketAsyncDataHandler<string> handler2 = new SocketAsyncDataHandler<string>(socket2, 2); var receiveSocketAsyncEventArgs2 = _socketAsyncEventArgsPool.Pop(); _bufferManager.SetBuffer(receiveSocketAsyncEventArgs2); handler2.StartReceiveDataFrom ( remoteAnyIPEP , receiveSocketAsyncEventArgs2 , (x, y, z) => { Console.WriteLine("次数: {0}", x.ReceivedCount); Console.WriteLine("字节: {0}", y.Length); EasyPerformanceCountersHelper<CommonPerformanceCountersContainer> .CountPerformance ( enableCounters , performanceCountersCategoryName , "Hander2::Received" , null , () => { var ss = receiveEncoding.GetString(y); //Console.Write(s); Console.WriteLine ( "from {0} , to {1}, data {2}" , x.WorkingSocket.LocalEndPoint , z.RemoteEndPoint , ss ); } , null , null , null ); return false; } , (x, y, z) => { Console.WriteLine(z.ToString()); return true; } ); string s = string.Empty; Console.WriteLine("Send ..."); while ((s = Console.ReadLine().ToLower()) != "q") { var buffer = sendEncoding.GetBytes(s); Parallel.For ( 0 , 1000 , new ParallelOptions() { MaxDegreeOfParallelism = 1// Environment.ProcessorCount //, TaskScheduler = null } , i => { Thread.Sleep(5); EasyPerformanceCountersHelper<CommonPerformanceCountersContainer> .CountPerformance ( enableCounters , performanceCountersCategoryName , "Hander1::Sended" , null , () => { handler1.SendDataToSync(buffer, ipep2); } , null , null , null ); EasyPerformanceCountersHelper<CommonPerformanceCountersContainer> .CountPerformance ( enableCounters , performanceCountersCategoryName , "Hander2::Sended" , null , () => { handler2.SendDataToSync(buffer, ipep1); } , null , null , null ); } ); } var e = handler1.ReceiveSocketAsyncEventArgs; //_bufferManager.FreeBuffer(e); _socketAsyncEventArgsPool.Push(e); e = handler2.ReceiveSocketAsyncEventArgs; //_bufferManager.FreeBuffer(e); _socketAsyncEventArgsPool.Push(e); handler1.DestoryWorkingSocket(); handler2.DestoryWorkingSocket(); Console.WriteLine("Send quit"); } //private static int _recieveCount = 0; } } namespace Microshaoft { using System.Collections.Concurrent; using System.Net.Sockets; // Represents a collection of reusable SocketAsyncEventArgs objects. public class SocketAsyncEventArgsPool { private ConcurrentStack<SocketAsyncEventArgs> _pool; public SocketAsyncEventArgsPool(int count) { _pool = new ConcurrentStack<SocketAsyncEventArgs>(); for (var i = 0; i < count; i++) { _pool.Push(new SocketAsyncEventArgs()); } } // Add a SocketAsyncEventArg instance to the pool // //The "item" parameter is the SocketAsyncEventArgs instance // to add to the pool public void Push(SocketAsyncEventArgs socketAsyncEventArgs) { _pool.Push(socketAsyncEventArgs); } // Removes a SocketAsyncEventArgs instance from the pool // and returns the object removed from the pool public SocketAsyncEventArgs Pop() { SocketAsyncEventArgs socketAsyncEventArgs = null; if ( _pool.IsEmpty || !_pool.TryPop(out socketAsyncEventArgs) ) { socketAsyncEventArgs = new SocketAsyncEventArgs(); } return socketAsyncEventArgs; } // The number of SocketAsyncEventArgs instances in the pool public int Count { get { return _pool.Count; } } } } namespace Microshaoft { using System.Collections.Concurrent; using System.Net.Sockets; public class BufferManager { // This class creates a single large buffer which can be divided up // and assigned to SocketAsyncEventArgs objects for use with each // socket I/O operation. // This enables buffers to be easily reused and guards against // fragmenting heap memory. // //This buffer is a byte array which the Windows TCP buffer can copy its data to. // the total number of bytes controlled by the buffer pool int _totalBytesInBufferBlock; // Byte array maintained by the Buffer Manager. byte[] _bufferBlock; ConcurrentStack<int> _freeIndexPool; int _currentIndex; int _bufferBytesAllocatedForEachSaea; public BufferManager(int totalBytes, int totalBufferBytesInEachSaeaObject) { _totalBytesInBufferBlock = totalBytes; _currentIndex = 0; _bufferBytesAllocatedForEachSaea = totalBufferBytesInEachSaeaObject; _freeIndexPool = new ConcurrentStack<int>(); } // Allocates buffer space used by the buffer pool public void InitBuffer() { // Create one large buffer block. _bufferBlock = new byte[_totalBytesInBufferBlock]; } // Divide that one large buffer block out to each SocketAsyncEventArg object. // Assign a buffer space from the buffer block to the // specified SocketAsyncEventArgs object. // // returns true if the buffer was successfully set, else false public bool SetBuffer(SocketAsyncEventArgs args) { int index = -1; if (_freeIndexPool.TryPop(out index)) { //This if-statement is only true if you have called the FreeBuffer //method previously, which would put an offset for a buffer space //back into this stack. args.SetBuffer(_bufferBlock, index, _bufferBytesAllocatedForEachSaea); } else { //Inside this else-statement is the code that is used to set the //buffer for each SAEA object when the pool of SAEA objects is built //in the Init method. if ((_totalBytesInBufferBlock - _bufferBytesAllocatedForEachSaea) < _currentIndex) { return false; } args.SetBuffer(_bufferBlock, _currentIndex, _bufferBytesAllocatedForEachSaea); _currentIndex += _bufferBytesAllocatedForEachSaea; } return true; } // Removes the buffer from a SocketAsyncEventArg object. This frees the // buffer back to the buffer pool. Try NOT to use the FreeBuffer method, // unless you need to destroy the SAEA object, or maybe in the case // of some exception handling. Instead, on the server // keep the same buffer space assigned to one SAEA object for the duration of // this app's running. private void FreeBuffer(SocketAsyncEventArgs args) { _freeIndexPool.Push(args.Offset); args.SetBuffer(null, 0, 0); } } } namespace Microshaoft { using System; using System.Net; using System.Net.Sockets; using System.Threading; public class SocketAsyncDataHandler<T> { private Socket _socket; public Socket WorkingSocket { get { return _socket; } } //public int ReceiveDataBufferLength //{ // get; // private set; //} public T ConnectionToken { get; set; } public IPAddress RemoteIPAddress { get { return ((IPEndPoint) _socket.RemoteEndPoint).Address; } } public IPAddress LocalIPAddress { get { return ((IPEndPoint) _socket.LocalEndPoint).Address; } } public int SocketID { get; private set; } public SocketAsyncDataHandler ( Socket socket , int socketID ) { _socket = socket; _isUdp = (_socket.ProtocolType == ProtocolType.Udp); _sendSocketAsyncEventArgs = new SocketAsyncEventArgs(); SocketID = socketID; } private SocketAsyncEventArgs _sendSocketAsyncEventArgs; public int HeaderBytesLength { get; private set; } public int HeaderBytesOffset { get; private set; } private long _receivedCount = 0; public long ReceivedCount { get { return _receivedCount; } } public int HeaderBytesCount { get; private set; } public SocketAsyncEventArgs ReceiveSocketAsyncEventArgs { get; private set; } private bool _isStartedReceiveData = false; private bool _isHeader = true; public bool StartReceiveWholeDataPackets ( int headerBytesLength , int headerBytesOffset , int headerBytesCount , Func<SocketAsyncEventArgs> getReceiveSocketAsyncEventArgsProcessFunc , Func < SocketAsyncDataHandler<T> , byte[] , SocketAsyncEventArgs , bool > onOneWholeDataPacketReceivedProcessFunc , Func < SocketAsyncDataHandler<T> , byte[] , SocketAsyncEventArgs , bool > onReceivedDataPacketErrorProcessFunc = null , Func < SocketAsyncDataHandler<T> , SocketAsyncEventArgs , Exception , bool > onCaughtExceptionProcessFunc = null ) { return StartReceiveWholeDataPackets ( headerBytesLength , headerBytesOffset , headerBytesCount , getReceiveSocketAsyncEventArgsProcessFunc() , onOneWholeDataPacketReceivedProcessFunc , onReceivedDataPacketErrorProcessFunc , onCaughtExceptionProcessFunc ); } public bool StartReceiveWholeDataPackets ( int headerBytesLength , int headerBytesOffset , int headerBytesCount , SocketAsyncEventArgs receiveSocketAsyncEventArgs , Func < SocketAsyncDataHandler<T> , byte[] , SocketAsyncEventArgs , bool > onOneWholeDataPacketReceivedProcessFunc , Func < SocketAsyncDataHandler<T> , byte[] , SocketAsyncEventArgs , bool > onReceivedDataPacketErrorProcessFunc = null , Func < SocketAsyncDataHandler<T> , SocketAsyncEventArgs , Exception , bool > onCaughtExceptionProcessFunc = null ) { if (!_isStartedReceiveData) { HeaderBytesLength = headerBytesLength; HeaderBytesOffset = headerBytesOffset; HeaderBytesCount = headerBytesCount; int bodyLength = 0; ReceiveSocketAsyncEventArgs = receiveSocketAsyncEventArgs; ReceiveSocketAsyncEventArgs.Completed += new EventHandler<SocketAsyncEventArgs> ( (sender, e) => { var socket = sender as Socket; if (e.BytesTransferred >= 0) { byte[] buffer = e.Buffer; int r = e.BytesTransferred; int p = e.Offset; int l = e.Count; if (r < l) { p += r; e.SetBuffer(p, l - r); } else if (r == l) { if (_isHeader) { byte[] data = new byte[headerBytesCount]; Buffer.BlockCopy ( buffer , HeaderBytesOffset , data , 0 , data.Length ); byte[] intBytes = new byte[4]; l = (intBytes.Length < HeaderBytesCount ? intBytes.Length : HeaderBytesCount); Buffer.BlockCopy ( data , 0 , intBytes , 0 , l ); //Array.Reverse(intBytes); bodyLength = BitConverter.ToInt32(intBytes, 0); p += r; e.SetBuffer(p, bodyLength); Console.WriteLine(bodyLength); _isHeader = false; } else { byte[] data = new byte[bodyLength + HeaderBytesLength]; bodyLength = 0; Buffer.BlockCopy(buffer, 0, data, 0, data.Length); _isHeader = true; e.SetBuffer(0, HeaderBytesLength); if (onOneWholeDataPacketReceivedProcessFunc != null) { onOneWholeDataPacketReceivedProcessFunc ( this , data , e ); } } } else { if (onReceivedDataPacketErrorProcessFunc != null) { byte[] data = new byte[p + r + HeaderBytesLength]; Buffer.BlockCopy(buffer, 0, data, 0, data.Length); bool b = onReceivedDataPacketErrorProcessFunc ( this , data , e ); if (b) { bool i = DestoryWorkingSocket(); } else { _isHeader = true; e.SetBuffer(0, HeaderBytesLength); } } } } if (!_isWorkingSocketDestoryed) { try { socket.ReceiveAsync(e); } catch (Exception exception) { var r = false; if (onCaughtExceptionProcessFunc != null) { r = onCaughtExceptionProcessFunc ( this , e , exception ); } if (r) { DestoryWorkingSocket(); } } } } ); _socket.ReceiveAsync(ReceiveSocketAsyncEventArgs); _isStartedReceiveData = true; } return _isStartedReceiveData; } private bool _isUdp = false; public bool IsUdp { get { return _isUdp; } } private bool _isWorkingSocketDestoryed = false; public bool DestoryWorkingSocket() { //bool r = false; try { if (_socket.Connected) { _socket.Disconnect(false); } _socket.Shutdown(SocketShutdown.Both); _socket.Close(); _socket.Dispose(); _socket = null; _isWorkingSocketDestoryed = true; } catch (Exception e) { Console.WriteLine(e.ToString()); //r = false; } return _isWorkingSocketDestoryed; } public bool StartReceiveDataFrom ( EndPoint remoteEndPoint , Func<SocketAsyncEventArgs> getReceiveSocketAsyncEventArgsProcessFunc , Func < SocketAsyncDataHandler<T> , byte[] , SocketAsyncEventArgs , bool > onDataReceivedProcessFunc , Func < SocketAsyncDataHandler<T> , SocketAsyncEventArgs , Exception , bool > onCaughtExceptionProcessFunc = null ) { return StartReceiveDataFrom ( remoteEndPoint , getReceiveSocketAsyncEventArgsProcessFunc() , onDataReceivedProcessFunc , onCaughtExceptionProcessFunc ); } public bool StartReceiveDataFrom ( EndPoint remoteEndPoint , SocketAsyncEventArgs receiveSocketAsyncEventArgs , Func < SocketAsyncDataHandler<T> , byte[] , SocketAsyncEventArgs , bool > onDataReceivedProcessFunc , Func < SocketAsyncDataHandler<T> , SocketAsyncEventArgs , Exception , bool > onCaughtExceptionProcessFunc = null ) { if (!_isStartedReceiveData) { ReceiveSocketAsyncEventArgs = receiveSocketAsyncEventArgs; ReceiveSocketAsyncEventArgs.RemoteEndPoint = remoteEndPoint; ReceiveSocketAsyncEventArgs.Completed += new EventHandler<SocketAsyncEventArgs> ( (sender, e) => { Interlocked.Increment(ref _receivedCount); var socket = sender as Socket; int l = e.BytesTransferred; //Console.WriteLine(l); if (l > 0) { byte[] data = new byte[l]; var buffer = e.Buffer; Buffer.BlockCopy(buffer, 0, data, 0, data.Length); if (onDataReceivedProcessFunc != null) { onDataReceivedProcessFunc(this, data, e); //Console.WriteLine(_receivedCount); } } if (!_isWorkingSocketDestoryed) { try { socket.ReceiveFromAsync(ReceiveSocketAsyncEventArgs); } catch (Exception exception) { //Console.WriteLine(exception.ToString()); var r = false; if (onCaughtExceptionProcessFunc != null) { r = onCaughtExceptionProcessFunc(this, ReceiveSocketAsyncEventArgs, exception); } if (r) { DestoryWorkingSocket(); } } } } ); _socket.ReceiveFromAsync(ReceiveSocketAsyncEventArgs); _isStartedReceiveData = true; } return _isStartedReceiveData; } private object _sendSyncLockObject = new object(); public int SendDataSync(byte[] data) { var r = -1; if (!_isUdp) { lock (_sendSyncLockObject) { r = _socket.Send(data); } } return r; } public int SendDataSyncWithRetry ( byte[] data , int retry = 3 , int sleepSeconds = 1 ) { //增加就地重试机制 int r = -1; int i = 0; while (i < retry) { r = -1; //lock (_sendSyncLockObject) { try { if (_socket != null) { r = SendDataSync(data); } } catch (Exception e) { Console.WriteLine(e.ToString()); } } i++; if (r > 0 || i == retry) { break; } else { Thread.Sleep(sleepSeconds * 1000); } } return r; } public int SendDataToSync(byte[] data, EndPoint remoteEndPoint) { var r = -1; if (_isUdp) { lock (_sendSyncLockObject) { r = _socket.SendTo(data, remoteEndPoint); } } return r; } public int SendDataToSyncWithRetry ( byte[] data , EndPoint remoteEndPoint , int retry = 3 , int sleepSeconds = 1 ) { //增加就地重试机制 int r = -1; int i = 0; while (i < retry) { r = -1; lock (_sendSyncLockObject) { try { if (_socket != null) { r = _socket.SendTo(data, remoteEndPoint); } } catch (Exception e) { Console.WriteLine(e.ToString()); } } i++; if (r > 0 || i == retry) { break; } else { Thread.Sleep(sleepSeconds * 1000); } } return r; } } } namespace TestConsoleApplication { using System; using System.Diagnostics; using System.Threading; using System.Threading.Tasks; using Microshaoft; class Program { static void Main1(string[] args) { Console.WriteLine("Begin ..."); Random r = new Random(); int sleep = 2; int iterations = 10; int maxDegreeOfParallelism = 8; // Environment.ProcessorCount; var performanceCountersCategoryName = "Microshaoft EasyPerformanceCounters Category"; var performanceCountersCategoryInstanceName = string.Format ( "{2}{0}{3}{1}{4}" , ": " , " @ " , "" , "" , Process.GetCurrentProcess().ProcessName ); //EasyPerformanceCountersHelper 调用示例 EasyPerformanceCountersHelper<CommonPerformanceCountersContainer> .AttachPerformanceCountersCategoryInstance ( performanceCountersCategoryName , performanceCountersCategoryInstanceName + "-1" ); EasyPerformanceCountersHelper<CommonPerformanceCountersContainer> .AttachPerformanceCountersCategoryInstance ( performanceCountersCategoryName , performanceCountersCategoryInstanceName + "-2" ); var enableCounters = MultiPerformanceCountersTypeFlags.ProcessCounter | MultiPerformanceCountersTypeFlags.ProcessedAverageTimerCounter | MultiPerformanceCountersTypeFlags.ProcessedCounter | MultiPerformanceCountersTypeFlags.ProcessedRateOfCountsPerSecondCounter | MultiPerformanceCountersTypeFlags.ProcessingCounter; Parallel.For ( 0 , iterations , new ParallelOptions() { MaxDegreeOfParallelism = maxDegreeOfParallelism } , (x) => { EasyPerformanceCountersHelper<CommonPerformanceCountersContainer> .CountPerformance ( enableCounters , performanceCountersCategoryName , performanceCountersCategoryInstanceName + "-1" , null , () => { sleep = r.Next(0, 5) * 1000; //Thread.Sleep(sleep); throw new Exception("sadsad"); } , null , (xx) => { //Console.WriteLine("Exception {0}", xx.ToString()); return false; } , null ); } ); Parallel.For ( 0 , iterations , new ParallelOptions() { MaxDegreeOfParallelism = maxDegreeOfParallelism } , (x) => { Stopwatch stopwatch = null; try { stopwatch = EasyPerformanceCountersHelper<CommonPerformanceCountersContainer> .CountPerformanceBegin ( enableCounters , performanceCountersCategoryName , performanceCountersCategoryInstanceName + "-2" ); sleep = r.Next(0, 5) * 1000; //Thread.Sleep(sleep); throw new Exception("Test"); } catch { } finally { EasyPerformanceCountersHelper<CommonPerformanceCountersContainer> .CountPerformanceEnd ( enableCounters , performanceCountersCategoryName , performanceCountersCategoryInstanceName + "-2" , stopwatch ); } } ); Console.WriteLine("End ..."); Console.ReadLine(); } } } namespace Microshaoft { using System; using System.Collections.Generic; using System.Diagnostics; //using System.Collections.Concurrent; public static class EasyPerformanceCountersHelper<TPerformanceCountersContainer> where TPerformanceCountersContainer : class, IPerformanceCountersContainer, new () { private static Dictionary<string, TPerformanceCountersContainer> _dictionary = new Dictionary<string, TPerformanceCountersContainer>(); public static void AttachPerformanceCountersCategoryInstance ( string performanceCountersCategoryName , string performanceCountersCategoryInstanceName ) { string key = string.Format ( "{1}{0}{2}" , "-" , performanceCountersCategoryName , performanceCountersCategoryInstanceName ); TPerformanceCountersContainer container = null; if (!_dictionary.TryGetValue(key, out container)) { container = new TPerformanceCountersContainer(); _dictionary.Add ( key , container ); container .AttachPerformanceCountersToProperties ( performanceCountersCategoryInstanceName , performanceCountersCategoryName ); } } private static object _lockerObject = new object(); public static Stopwatch CountPerformanceBegin ( MultiPerformanceCountersTypeFlags enabledPerformanceCounters , string performanceCountersCategoryName , string performanceCountersCategoryInstanceName ) { Stopwatch r = null; if (enabledPerformanceCounters != MultiPerformanceCountersTypeFlags.None) { string key = string.Format ( "{1}{0}{2}" , "-" , performanceCountersCategoryName , performanceCountersCategoryInstanceName ); TPerformanceCountersContainer container = null; if (!_dictionary.TryGetValue(key, out container)) { lock (_lockerObject) { container = new TPerformanceCountersContainer(); _dictionary.Add ( key , container ); container.AttachPerformanceCountersToProperties ( performanceCountersCategoryInstanceName , performanceCountersCategoryName ); } } var enableProcessCounter = ( ( enabledPerformanceCounters & MultiPerformanceCountersTypeFlags.ProcessCounter ) != MultiPerformanceCountersTypeFlags.None ); if (enableProcessCounter) { container.PrcocessPerformanceCounter.Increment(); } var enableProcessingCounter = ( ( enabledPerformanceCounters & MultiPerformanceCountersTypeFlags.ProcessingCounter ) != MultiPerformanceCountersTypeFlags.None ); if (enableProcessingCounter) { container.ProcessingPerformanceCounter.Increment(); } var enableProcessedAverageTimerCounter = ( ( enabledPerformanceCounters & MultiPerformanceCountersTypeFlags.ProcessedAverageTimerCounter ) != MultiPerformanceCountersTypeFlags.None ); if (enableProcessedAverageTimerCounter) { r = Stopwatch.StartNew(); } } return r; } public static void CountPerformanceEnd ( MultiPerformanceCountersTypeFlags enabledPerformanceCounters , string performanceCountersCategoryName , string performanceCountersCategoryInstanceName , Stopwatch stopwatch ) { string key = string.Format ( "{1}{0}{2}" , "-" , performanceCountersCategoryName , performanceCountersCategoryInstanceName ); TPerformanceCountersContainer container = null; if (!_dictionary.TryGetValue(key, out container)) { return; } var enableProcessedAverageTimerCounter = ( ( enabledPerformanceCounters & MultiPerformanceCountersTypeFlags.ProcessedAverageTimerCounter ) != MultiPerformanceCountersTypeFlags.None ); if (enableProcessedAverageTimerCounter) { if (stopwatch != null) { PerformanceCounter performanceCounter = container.ProcessedAverageTimerPerformanceCounter; PerformanceCounter basePerformanceCounter = container.ProcessedAverageBasePerformanceCounter; stopwatch.Stop(); performanceCounter.IncrementBy(stopwatch.ElapsedTicks); basePerformanceCounter.Increment(); //stopwatch = null; } } var enableProcessingCounter = ( ( enabledPerformanceCounters & MultiPerformanceCountersTypeFlags.ProcessingCounter ) != MultiPerformanceCountersTypeFlags.None ); if (enableProcessingCounter) { container.ProcessingPerformanceCounter.Decrement(); } var enableProcessedPerformanceCounter = ( ( enabledPerformanceCounters & MultiPerformanceCountersTypeFlags.ProcessedCounter ) != MultiPerformanceCountersTypeFlags.None ); if (enableProcessedPerformanceCounter) { container.ProcessedPerformanceCounter.Increment(); } var enableProcessedRateOfCountsPerSecondPerformanceCounter = ( ( enabledPerformanceCounters & MultiPerformanceCountersTypeFlags.ProcessedRateOfCountsPerSecondCounter ) != MultiPerformanceCountersTypeFlags.None ); if (enableProcessedRateOfCountsPerSecondPerformanceCounter) { container.ProcessedRateOfCountsPerSecondPerformanceCounter.Increment(); } } public static void CountPerformance ( MultiPerformanceCountersTypeFlags enabledPerformanceCounters , string performanceCountersCategoryName , string performanceCountersCategoryInstanceName , Action onBeforeCountPerformanceInnerProcessAction , Action onCountPerformanceInnerProcessAction , Action onAfterCountPerformanceInnerProcessAction , Func<Exception, bool> onCaughtExceptionProcessFunc , Action<bool, Exception> onFinallyProcessAction ) { if (enabledPerformanceCounters != MultiPerformanceCountersTypeFlags.None) { if (onCountPerformanceInnerProcessAction != null) { string key = string.Format ( "{1}{0}{2}" , "-" , performanceCountersCategoryName , performanceCountersCategoryInstanceName ); TPerformanceCountersContainer container = null; if (!_dictionary.TryGetValue(key, out container)) { lock (_lockerObject) { container = new TPerformanceCountersContainer(); _dictionary.Add ( key , container ); container.AttachPerformanceCountersToProperties ( performanceCountersCategoryInstanceName , performanceCountersCategoryName ); } } var enableProcessCounter = ( ( enabledPerformanceCounters & MultiPerformanceCountersTypeFlags.ProcessCounter ) != MultiPerformanceCountersTypeFlags.None ); if (enableProcessCounter) { container.PrcocessPerformanceCounter.Increment(); } var enableProcessingCounter = ( ( enabledPerformanceCounters & MultiPerformanceCountersTypeFlags.ProcessingCounter ) != MultiPerformanceCountersTypeFlags.None ); if (enableProcessingCounter) { container.ProcessingPerformanceCounter.Increment(); } var enableProcessedAverageTimerCounter = ( ( enabledPerformanceCounters & MultiPerformanceCountersTypeFlags.ProcessedAverageTimerCounter ) != MultiPerformanceCountersTypeFlags.None ); var reThrowException = false; container .ProcessedAverageTimerPerformanceCounter .ChangeAverageTimerCounterValueWithTryCatchExceptionFinally ( enableProcessedAverageTimerCounter , container.ProcessedAverageBasePerformanceCounter , () => { if (onCountPerformanceInnerProcessAction != null) { if (onBeforeCountPerformanceInnerProcessAction != null) { onBeforeCountPerformanceInnerProcessAction(); } onCountPerformanceInnerProcessAction(); if (onAfterCountPerformanceInnerProcessAction != null) { onAfterCountPerformanceInnerProcessAction(); } } } , (x, y) => //catch { container .CaughtExceptionsPerformanceCounter .Increment(); var r = reThrowException; if (onCaughtExceptionProcessFunc != null) { r = onCaughtExceptionProcessFunc(y); } return r; } , (x, y, z, w) => //Finally { if (enableProcessingCounter) { container.ProcessingPerformanceCounter.Decrement(); } var enableProcessedPerformanceCounter = ( ( enabledPerformanceCounters & MultiPerformanceCountersTypeFlags.ProcessedCounter ) != MultiPerformanceCountersTypeFlags.None ); if (enableProcessedPerformanceCounter) { container.ProcessedPerformanceCounter.Increment(); } var enableProcessedRateOfCountsPerSecondPerformanceCounter = ( ( enabledPerformanceCounters & MultiPerformanceCountersTypeFlags.ProcessedRateOfCountsPerSecondCounter ) != MultiPerformanceCountersTypeFlags.None ); if (enableProcessedRateOfCountsPerSecondPerformanceCounter) { container .ProcessedRateOfCountsPerSecondPerformanceCounter .Increment(); } } ); } } else { if (onCountPerformanceInnerProcessAction != null) { onCountPerformanceInnerProcessAction(); } } } } } namespace Microshaoft { using System.Diagnostics; public interface IPerformanceCountersContainer { PerformanceCounter CaughtExceptionsPerformanceCounter { get; } PerformanceCounter PrcocessPerformanceCounter { get; } PerformanceCounter ProcessingPerformanceCounter { get; } PerformanceCounter ProcessedPerformanceCounter { get; } PerformanceCounter ProcessedRateOfCountsPerSecondPerformanceCounter { get; } PerformanceCounter ProcessedAverageTimerPerformanceCounter { get; } PerformanceCounter ProcessedAverageBasePerformanceCounter { get; } void AttachPerformanceCountersToProperties ( string instanceName , string categoryName ); } } namespace Microshaoft { using System; using System.Diagnostics; public class CommonPerformanceCountersContainer : IPerformanceCountersContainer { #region PerformanceCounters private PerformanceCounter _caughtExceptionsPerformanceCounter; [ PerformanceCounterDefinitionAttribute ( CounterType = PerformanceCounterType.NumberOfItems64 , CounterName = "99.捕获异常次数(次)" ) ] public PerformanceCounter CaughtExceptionsPerformanceCounter { private set { ReaderWriterLockSlimHelper .TryEnterWriterLockSlimWrite<PerformanceCounter> ( ref _caughtExceptionsPerformanceCounter , value , 2 ); } get { return _caughtExceptionsPerformanceCounter; } } private PerformanceCounter _processPerformanceCounter; [ PerformanceCounterDefinitionAttribute ( CounterType = PerformanceCounterType.NumberOfItems64 , CounterName = "01.接收处理笔数(笔)" ) ] public PerformanceCounter PrcocessPerformanceCounter { private set { ReaderWriterLockSlimHelper .TryEnterWriterLockSlimWrite<PerformanceCounter> ( ref _processPerformanceCounter , value , 2 ); } get { return _processPerformanceCounter; } } private PerformanceCounter _processingPerformanceCounter; [ PerformanceCounterDefinitionAttribute ( CounterType = PerformanceCounterType.NumberOfItems64 , CounterName = "02.正在处理笔数(笔)" ) ] public PerformanceCounter ProcessingPerformanceCounter { private set { ReaderWriterLockSlimHelper .TryEnterWriterLockSlimWrite<PerformanceCounter> ( ref _processingPerformanceCounter , value , 2 ); } get { return _processingPerformanceCounter; } } private PerformanceCounter _processedPerformanceCounter; [ PerformanceCounterDefinitionAttribute ( CounterType = PerformanceCounterType.NumberOfItems64 , CounterName = "03.完成处理笔数(笔)" ) ] public PerformanceCounter ProcessedPerformanceCounter { private set { ReaderWriterLockSlimHelper .TryEnterWriterLockSlimWrite<PerformanceCounter> ( ref _processedPerformanceCounter , value , 2 ); } get { return _processedPerformanceCounter; } } private PerformanceCounter _processedRateOfCountsPerSecondPerformanceCounter; [ PerformanceCounterDefinitionAttribute ( CounterType = PerformanceCounterType.RateOfCountsPerSecond64 , CounterName = "04.每秒完成处理笔数(笔/秒)" ) ] public PerformanceCounter ProcessedRateOfCountsPerSecondPerformanceCounter { private set { ReaderWriterLockSlimHelper .TryEnterWriterLockSlimWrite<PerformanceCounter> ( ref _processedRateOfCountsPerSecondPerformanceCounter , value , 2 ); } get { return _processedRateOfCountsPerSecondPerformanceCounter; } } private PerformanceCounter _ProcessedAverageTimerPerformanceCounter; [ PerformanceCounterDefinitionAttribute ( CounterType = PerformanceCounterType.AverageTimer32 , CounterName = "05.平均每笔处理耗时秒数(秒/笔)" ) ] public PerformanceCounter ProcessedAverageTimerPerformanceCounter { private set { ReaderWriterLockSlimHelper .TryEnterWriterLockSlimWrite<PerformanceCounter> ( ref _ProcessedAverageTimerPerformanceCounter , value , 2 ); } get { return _ProcessedAverageTimerPerformanceCounter; } } private PerformanceCounter _processedAverageBasePerformanceCounter; [ PerformanceCounterDefinitionAttribute ( CounterType = PerformanceCounterType.AverageBase ) ] public PerformanceCounter ProcessedAverageBasePerformanceCounter { private set { ReaderWriterLockSlimHelper .TryEnterWriterLockSlimWrite<PerformanceCounter> ( ref _processedAverageBasePerformanceCounter , value , 2 ); } get { return _processedAverageBasePerformanceCounter; } } #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 ) { var type = this.GetType(); PerformanceCountersHelper .AttachPerformanceCountersToProperties<CommonPerformanceCountersContainer> ( instanceName , categoryName , this ); } } } //========================================================================================= //========================================================================================= namespace Microshaoft { using System; using System.Diagnostics; public static class PerformanceCounterExtensionMethodsManager { public static void ChangeAverageTimerCounterValueWithTryCatchExceptionFinally ( this PerformanceCounter performanceCounter , bool enabled , PerformanceCounter basePerformanceCounter , Action onCountPerformanceInnerProcessAction //= null , Func<PerformanceCounter, Exception, bool> onCaughtExceptionProcessFunc //= null , Action<PerformanceCounter, PerformanceCounter, bool, Exception> onFinallyProcessAction //= null ) { if (enabled) { var stopwatch = Stopwatch.StartNew(); if (onCountPerformanceInnerProcessAction != null) { bool reThrowException = false; TryCatchFinallyProcessHelper .TryProcessCatchFinally ( true , () => { onCountPerformanceInnerProcessAction(); } , reThrowException , (x) => { var r = reThrowException; if (onCaughtExceptionProcessFunc != null) { r = onCaughtExceptionProcessFunc(performanceCounter, x); } return r; } , (x, y) => { 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.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 newValue , int enterTimeOutSeconds ) where T : class { bool r = false; var rwls = new ReaderWriterLockSlim(); int timeOut = Timeout.Infinite; if (enterTimeOutSeconds >= 0) { timeOut = enterTimeOutSeconds * 1000; } try { r = (rwls.TryEnterWriteLock(timeOut)); if (r) { Interlocked.Exchange<T>(ref target, newValue); r = true; } } finally { if (r) { rwls.ExitWriteLock(); } } return r; } public static bool TryEnterWriterLockSlim ( Action action , int enterTimeOutSeconds ) { bool r = false; if (action != null) { var rwls = new ReaderWriterLockSlim(); int timeOut = Timeout.Infinite; if (enterTimeOutSeconds >= 0) { timeOut = enterTimeOutSeconds * 1000; } try { r = (rwls.TryEnterWriteLock(timeOut)); if (r) { action(); r = true; } } finally { if (r) { rwls.ExitWriteLock(); } } } return r; } } } namespace Microshaoft { using System; using System.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.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; 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(); } } } 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; 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); } if (reThrowException) { throw new Exception ( innerExceptionMessage , e ); } } finally { //Console.WriteLine("Finally"); if (onFinallyProcessAction != null) { onFinallyProcessAction(caughtException, exception); } } } else { onTryProcessAction(); } } } } } |