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}]"
, "\r\n\t"
, 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}]"
, "\r\n\t"
, 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();
}
}
}
}
}
|