JsonHelper developed by using Newtonsoft.Json.NET, Deserialize to object , XmlToJson/JsonToXml, QuoteName by using JToken Path.

时间:2023-03-09 16:16:56
JsonHelper developed by using Newtonsoft.Json.NET, Deserialize to <T> object , XmlToJson/JsonToXml, QuoteName by using JToken Path.


namespace TestConsoleApplication

{

    using System;

    using System.Diagnostics;

    using System.Threading;

    using System.Threading.Tasks;

    using Microshaoft;

    using Microshaoft.Share;

    class Program

    {

        static void Main(string[] args)

        {

            ;

            ; // Environment.ProcessorCount;

            var performanceCountersCategoryName = "Microshaoft EasyPerformanceCounters Category";

            var performanceCountersCategoryInstanceName

                    = string.Format

                            (

                                "{2}{0}{3}{1}{4}"

                                , ": "

                                , " @ "

                                , ""

                                , "Json Performance Test"

                                , Process.GetCurrentProcess().ProcessName

                            );

            //EasyPerformanceCountersHelper 调用示例

            EasyPerformanceCountersHelper<CommonPerformanceCountersContainer>

                .AttachPerformanceCountersCategoryInstance

                                (

                                    performanceCountersCategoryName

                                    , performanceCountersCategoryInstanceName

                                );

            var enableCounters = MultiPerformanceCountersTypeFlags.ProcessCounter

                                    | MultiPerformanceCountersTypeFlags.ProcessedAverageTimerCounter

                                    | MultiPerformanceCountersTypeFlags.ProcessedCounter

                                    | MultiPerformanceCountersTypeFlags.ProcessedRateOfCountsPerSecondCounter

                                    | MultiPerformanceCountersTypeFlags.ProcessingCounter;

            Console.WriteLine("Press any key to Begin ...");

            Console.ReadLine();

            Parallel.For

                        (

                            , iterations

                            , new ParallelOptions()

                            {

                                MaxDegreeOfParallelism = maxDegreeOfParallelism

                            }

                            , (x) =>

                            {

                                EasyPerformanceCountersHelper<CommonPerformanceCountersContainer>

                                    .CountPerformance

                                        (

                                            enableCounters

                                            , performanceCountersCategoryName

                                            , performanceCountersCategoryInstanceName

                                            , null

                                            , () =>

                                            {

                                                ProcessOnce();

                                            }

                                            , null

                                            , (xx) =>

                                            {

                                                //Console.WriteLine("Exception {0}", xx.ToString());

                                                return false;

                                            }

                                            , null

                                        );

                            }

                        );

            Console.WriteLine("End ...");

            Console.ReadLine();

        }

        static void ProcessOnce()

        {

            var party = new Party()

            {

                PartyID = "clientID"

                 ,

                PartyInstanceID = "userID"

            };

            var loginRequestMessage = new LoginRequest()

            {

                Header = new MessageHeader()

                {

                    From = party

                    ,

                    To = new Party[]

                    {

                        party

                        , new Party()

                        {

                             PartyID = "1111111111"

                             ,

                             PartyInstanceID = "1111111-111111111"

                        }

                    }

                    ,

                    ,

                    SendTimeStamp = DateTime.Now

                    ,

                    Topic = "LoginRequest"

                    ,

                    ,

                    ID = Guid.NewGuid().ToString("N")

                    ,

                    LinkID = null

                    ,

                    Result = null

                }

                ,

                Body = new LoginRequestBody()

                {

                    Password = "password"

                }

            };

            Console.WriteLine("Json 序列化");

            var json = JsonHelper.Serialize(loginRequestMessage);

            Console.WriteLine(json);

            Console.WriteLine("Json 反序列化");

            var path = "H";

            var messageHeader = JsonHelper.DeserializeByJTokenPath<MessageHeader>(json, path);

            Console.WriteLine("JTokenPath: {0}, MessageHeader.Topic::Value: {1}", path, messageHeader.Topic);

            path = "B";

            var loginRequestBody = JsonHelper.DeserializeByJTokenPath<LoginRequestBody>(json, path);

            Console.WriteLine("JTokenPath: {0}, LoginRequestBody.Password::Value: {1}", path, loginRequestBody.Password);

            path = "H.To[1]";

            var party1 = JsonHelper.DeserializeByJTokenPath<Party>(json, path);

            Console.WriteLine("JTokenPath: {0}, Party.PartyID::Value: {1}", path, party1.PartyID);

            path = "";

            var loginRequest = JsonHelper.DeserializeByJTokenPath<LoginRequest>(json, path);

            Console.WriteLine("JTokenPath: {0}, LoginRequest.Header.ID::Value: {1}", path, loginRequest.Header.ID);

            Console.WriteLine("JTokenPath: {0}, LoginRequest.Body.Password::Value: {1}", path, loginRequest.Body.Password);

            var xml = JsonHelper.JsonToXml(json);

            Console.WriteLine(xml);

            json = JsonHelper.XmlToJson(xml);

            Console.WriteLine(json);

            //Console.ReadLine();

        }

    }

}

namespace Microshaoft.Share

{

    using Newtonsoft.Json;

    public class LoginRequest : IMessage

    {

        [JsonProperty("H")]

        public MessageHeader Header { get; set; }

        [JsonProperty("B")]

        public LoginRequestBody Body;

    }

    public class LoginRequestBody

    {

        [JsonProperty("P")]

        public string Password;

    }

    // CommonResponse

}

namespace Microshaoft.Share

{

    using Newtonsoft.Json;

    using System;

    public interface IMessage

    {

        MessageHeader Header { get; }

    }

    public class MessageHeader

    {

        // 消息主题

        [JsonProperty(PropertyName = "T")]

        public string Topic;

        // 消息号

        [JsonProperty(PropertyName = "I")]

        public string ID;

        // 关联消息号

        [JsonProperty(PropertyName = "L")]

        public string LinkID;

        // Require Response

        [JsonProperty(PropertyName = "R")]

        public int RequireResponse;

        // 发送方

        [JsonProperty(PropertyName = "F")]

        public Party From;

        // 接收方

        public Party[] To;

        // 发送时间戳

        [JsonProperty(PropertyName = "S")]

        public DateTime? SendTimeStamp;

        // 次数

        [JsonProperty(PropertyName = "C")]

        public int Count;

        // Result

        [JsonProperty(PropertyName = "V")]

        public int? Result;

    }

    public class Party

    {

        //PartyID

        [JsonProperty(PropertyName = "P")]

        public string PartyID;

        //PartyInstanceID

        [JsonProperty(PropertyName = "I")]

        public string PartyInstanceID;

    }

}

namespace Microshaoft

{

    using Newtonsoft.Json;

    using Newtonsoft.Json.Linq;

    using System;

    using System.IO;

    using System.Xml;

    public static class JsonHelper

    {

        public static string XmlToJson(string xml, bool keyQuoteName = false)

        {

            var xmlDocument = new XmlDocument();

            xmlDocument.LoadXml(xml);

            string json = string.Empty;

            using (var stringWriter = new StringWriter())

            {

                using (var jsonTextWriter = new JsonTextWriter(stringWriter))

                {

                    jsonTextWriter.QuoteName = keyQuoteName;

                    JsonSerializer jsonSerializer = new JsonSerializer();

                    jsonSerializer.Serialize(jsonTextWriter, xmlDocument);

                    json = stringWriter.ToString();

                }

            }

            return json;

        }

        public static string JsonToXml(string json, string deserializeRootElementName = "root", bool includeRoot = true)

        {

           // var s = string.Format("{{0}}", json);

            var xmlDocument = JsonConvert.DeserializeXmlNode(json, deserializeRootElementName);

            var xml = string.Empty;

            XmlNode xmlNode = null;

            if (!includeRoot)

            {

                xmlNode = xmlDocument.SelectSingleNode(deserializeRootElementName);

            }

            else

            {

                xmlNode = xmlDocument;

            }

            xml = xmlNode.InnerXml;

            return xml;

        }

        public static T DeserializeByJTokenPath<T>

            (

                string json

                , string jTokenPath = null //string.Empty

            )

        {

            JObject jObject = JObject.Parse(json);

            JsonSerializer jsonSerializer = new JsonSerializer();

            JToken jToken = jObject.SelectToken(jTokenPath);

            using (var jsonReader = jToken.CreateReader())

            {

                //Console.WriteLine(Environment.StackTrace);

                return jsonSerializer.Deserialize<T>(jsonReader);

            }

        }

        public static string Serialize(object target, bool keyQuoteName = false)

        {

            string json = string.Empty;

            using (StringWriter stringWriter = new StringWriter())

            {

                using (JsonTextWriter jsonTextWriter = new JsonTextWriter(stringWriter))

                {

                    jsonTextWriter.QuoteName = keyQuoteName;

                    JsonSerializer jsonSerializer = new JsonSerializer();

                    jsonSerializer.Serialize(jsonTextWriter, target);

                    json = stringWriter.ToString();

                }

            }

            return json;

        }

        public static void ReadJsonPathsValuesAsStrings

                            (

                                string json

                                , string[] jsonPaths

                                , Func<string, string, bool> onReadedOncePathStringValueProcesssFunc = null

                            )

        {

            using (var stringReader = new StringReader(json))

            {

                using (var jsonReader = new JsonTextReader(stringReader))

                {

                    bool breakAndReturn = false;

                    while

                        (

                            jsonReader.Read()

                            && !breakAndReturn

                        )

                    {

                        foreach (var x in jsonPaths)

                        {

                            if (x == jsonReader.Path)

                            {

                                if (onReadedOncePathStringValueProcesssFunc != null)

                                {

                                    var s = jsonReader.ReadAsString();

                                    breakAndReturn = onReadedOncePathStringValueProcesssFunc

                                            (

                                                x

                                                , s

                                            );

                                    if (breakAndReturn)

                                    {

                                        break;

                                    }

                                }

                            }

                        }

                    }

                }

            }

        }

    }

}

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

                        );

            }

            get

            {

                return _caughtExceptionsPerformanceCounter;

            }

        }

        private PerformanceCounter _processPerformanceCounter;

        [

            PerformanceCounterDefinitionAttribute

                (

                    CounterType = PerformanceCounterType.NumberOfItems64

                    , CounterName = "01.接收处理笔数(笔)"

                )

        ]

        public PerformanceCounter PrcocessPerformanceCounter

        {

            private set

            {

                ReaderWriterLockSlimHelper

                    .TryEnterWriterLockSlimWrite<PerformanceCounter>

                        (

                            ref _processPerformanceCounter

                            , value

                        );

            }

            get

            {

                return _processPerformanceCounter;

            }

        }

        private PerformanceCounter _processingPerformanceCounter;

        [

            PerformanceCounterDefinitionAttribute

                (

                    CounterType = PerformanceCounterType.NumberOfItems64

                    , CounterName = "02.正在处理笔数(笔)"

                )

        ]

        public PerformanceCounter ProcessingPerformanceCounter

        {

            private set

            {

                ReaderWriterLockSlimHelper

                    .TryEnterWriterLockSlimWrite<PerformanceCounter>

                        (

                            ref _processingPerformanceCounter

                            , value

                        );

            }

            get

            {

                return _processingPerformanceCounter;

            }

        }

        private PerformanceCounter _processedPerformanceCounter;

        [

            PerformanceCounterDefinitionAttribute

                (

                    CounterType = PerformanceCounterType.NumberOfItems64

                    , CounterName = "03.完成处理笔数(笔)"

                )

        ]

        public PerformanceCounter ProcessedPerformanceCounter

        {

            private set

            {

                ReaderWriterLockSlimHelper

                    .TryEnterWriterLockSlimWrite<PerformanceCounter>

                        (

                            ref _processedPerformanceCounter

                            , value

                        );

            }

            get

            {

                return _processedPerformanceCounter;

            }

        }

        private PerformanceCounter _processedRateOfCountsPerSecondPerformanceCounter;

        [

            PerformanceCounterDefinitionAttribute

                (

                    CounterType = PerformanceCounterType.RateOfCountsPerSecond64

                    , CounterName = "04.每秒完成处理笔数(笔/秒)"

                )

        ]

        public PerformanceCounter ProcessedRateOfCountsPerSecondPerformanceCounter

        {

            private set

            {

                ReaderWriterLockSlimHelper

                    .TryEnterWriterLockSlimWrite<PerformanceCounter>

                        (

                            ref _processedRateOfCountsPerSecondPerformanceCounter

                            , value

                        );

            }

            get

            {

                return _processedRateOfCountsPerSecondPerformanceCounter;

            }

        }

        private PerformanceCounter _ProcessedAverageTimerPerformanceCounter;

        [

            PerformanceCounterDefinitionAttribute

                (

                    CounterType = PerformanceCounterType.AverageTimer32

                    , CounterName = "05.平均每笔处理耗时秒数(秒/笔)"

                )

        ]

        public PerformanceCounter ProcessedAverageTimerPerformanceCounter

        {

            private set

            {

                ReaderWriterLockSlimHelper

                    .TryEnterWriterLockSlimWrite<PerformanceCounter>

                        (

                            ref _ProcessedAverageTimerPerformanceCounter

                            , value

                        );

            }

            get

            {

                return _ProcessedAverageTimerPerformanceCounter;

            }

        }

        private PerformanceCounter _processedAverageBasePerformanceCounter;

        [

            PerformanceCounterDefinitionAttribute

                (

                    CounterType = PerformanceCounterType.AverageBase

                )

        ]

        public PerformanceCounter ProcessedAverageBasePerformanceCounter

        {

            private set

            {

                ReaderWriterLockSlimHelper

                    .TryEnterWriterLockSlimWrite<PerformanceCounter>

                        (

                            ref _processedAverageBasePerformanceCounter

                            , value

                        );

            }

            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

    {

        ,

        ,

        ,

        ,

        ,

    };

    [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)

                                                            );

                                                    }

                                                ).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

                                        ,

                                    };

                                    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;

            )

            {

                ;

            }

            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;

                )

                {

                    ;

                }

                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();

                        );

                        var callerMethod = stackFrame.GetMethod();

                        var callerType = callerMethod.DeclaringType;

                        );

                        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);

                        );

                        var callerMethod = stackFrame.GetMethod();

                        var callerType = callerMethod.DeclaringType;

                        );

                        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();

                }

            }

        }

    }

}