• C# 监测每个方法的执行次数和占用时间(测试3)


    原文:http://www.cnblogs.com/RicCC/archive/2010/03/15/castle-dynamic-proxy.html

     在Nuget引用 Castle.DynamicProxy 和 Newtonsoft.Json 这个

    操作日志的作用:

        可用来分析方法的执行效率

        分析方法执行效率慢的原因

        根据传入的参数测试,找到运行瓶颈问题

    拦截器:

        /// <summary>
        /// 拦截器
        /// </summary>
        public class CallingLogInterceptor : IInterceptor
        {
            private DateTime dt { get; set; }
            private TimeSpan ts { get; set; }
    
            /// <summary>
            /// 方法执行前
            /// </summary>
            /// <param name="invocation"></param>
            private void PreProceed(IInvocation invocation)
            {
                dt = DateTime.Now;
            }
    
            /// <summary>
            /// 方法执行后
            /// </summary>
            /// <param name="invocation"></param>
            private void PostProceed(IInvocation invocation)
            {
                ts = DateTime.Now - dt;
                MethodOperationInfo.Add(invocation, ts.TotalMilliseconds);
            }
    
            /// <summary>
            /// 拦截
            /// </summary>
            /// <param name="invocation"></param>
            public void Intercept(IInvocation invocation)
            {
                this.PreProceed(invocation);
                invocation.Proceed();//调用
                this.PostProceed(invocation);
            }
        }
    View Code

    操作日志:

        /// <summary>
        /// 操作日志
        /// </summary>
        public class MethodOperationInfo
        {
            public string NameSpaceName { get; set; }
            public string ClassName { get; set; }
            public string MethodName { get; set; }
            public string Parameters { get; set; }
            public string ParameterTypes { get; set; }
            public double TotalMilliseconds { get; set; }
            public int ExecuteNumber { get; set; }
    
    
    
            public static List<MethodOperationInfo> list = new List<MethodOperationInfo>();//存放 详细信息
            public static Dictionary<string, MethodOperationInfo> dic = new Dictionary<string, MethodOperationInfo>();//存放 统计信息        
    
            /// <summary>
            /// 保证数据长度相同
            /// </summary>
            /// <param name="obj"></param>
            /// <param name="len"></param>
            /// <param name="afterFill">后填充/前填充</param>
            /// <returns></returns>
            public static string GetSameLenString(object obj, int len, bool afterFill = true)
            {
                string name = obj.ToString();
                int count = len - name.Length;
    
                if (afterFill)
                {
                    for (int i = 0; i < count; i++)
                    {
                        name += " ";
                    }
                    return name;
    
                }
                else
                {
                    string value = "";
                    for (int i = 0; i < count; i++)
                    {
                        value += " ";
                    }
                    value += name;
                    return value;
                }
            }
    
            /// <summary>
            /// 获取方法的参数类型
            /// 如:(System.String, System.Object, System.Int32)
            /// </summary>
            /// <param name="invocation"></param>
            /// <returns></returns>
            public static string GetParameterTypes(IInvocation invocation)
            {
                MethodInfo mInfo = invocation.Method;
                ParameterInfo[] pInfos = mInfo.GetParameters();
    
                string str = "";
                str += "(";
                for (int j = 0; j < pInfos.Length; j++)
                {
                    var p = pInfos[j];
                    string pTypeName = $"{p.ParameterType.ToString()}, ";
                    if (p.ParameterType.IsGenericType && (p.ParameterType.GetGenericTypeDefinition() == typeof(Nullable<>)))
                    {
                        pTypeName = $"{Nullable.GetUnderlyingType(p.ParameterType).Name}?, ";
                    }
                    str += pTypeName;
                }
                str = str.TrimEnd(' ').TrimEnd(',');
                str += ")";
    
                return str;
            }
    
            /// <summary>
            /// 获取方法的参数
            /// </summary>
            /// <param name="invocation"></param>
            /// <returns></returns>
            public static string GetParameter(IInvocation invocation)
            {
                string Parameters = "";//参数
                if ((invocation.Arguments != null) && (invocation.Arguments.Length > 0))
                {
                    Parameters = JsonConvert.SerializeObject(invocation.Arguments);
                }
                return Parameters;
            }
    
    
    
            /// <summary>
            /// 添加信息
            /// </summary>
            /// <param name="invocation"></param>
            /// <param name="TotalMilliseconds"></param>
            public static void Add(IInvocation invocation, double TotalMilliseconds)
            {
                string NameSpaceName = invocation.TargetType.Namespace;
                string ClassName = invocation.TargetType.Name;
                string MethodName = invocation.Method.Name;//方法名
                string ParameterTypes = GetParameterTypes(invocation);
                string Parameters = GetParameter(invocation);//参数
    
                //添加到 list
                var model = new MethodOperationInfo
                {
                    NameSpaceName = NameSpaceName,
                    ClassName = ClassName,
                    MethodName = MethodName,
                    ParameterTypes = ParameterTypes,
                    Parameters = Parameters,
                    TotalMilliseconds = TotalMilliseconds,
                    ExecuteNumber = 1
                };
                list.Add(model);
    
                //添加到 dictionary
                string key = MethodName + ParameterTypes;
                if (dic.ContainsKey(key))
                {
                    dic[key].TotalMilliseconds += TotalMilliseconds;
                    dic[key].ExecuteNumber += 1;
                }
                else
                {
                    dic.Add(key, model.MemberwiseClone() as MethodOperationInfo);
                }
            }
    
            /// <summary>
            /// 显示日志
            /// </summary>
            /// <param name="ShowDetailRecord">是否显示详情记录-比较占用时间</param>
            /// <param name="IsFilter">是否开启过滤</param>
            public static void Show(bool ShowDetailRecord = true, bool IsFilter = false)
            {
                StringBuilder sb = new StringBuilder();
                DateTime beforDT = DateTime.Now;
                List<string> list_Show_Method = new List<string>() { "GetSingle_Value1" };//可改为配置参数
    
    
    
                //每个方法-耗时            
                string str = "";
                double TotalMilliseconds = 0;
                foreach (var item in dic)
                {
                    TotalMilliseconds += item.Value.TotalMilliseconds;
    
                    str += $"命名空间:{GetSameLenString(item.Value.NameSpaceName, 40)}     ";
                    str += $"类名:{GetSameLenString(item.Value.ClassName, 30)}     ";
                    str += $"方法:{GetSameLenString(item.Key, 80)}     ";
                    str += $"次数:{GetSameLenString(item.Value.ExecuteNumber, 10)}     ";
                    str += $"耗时:{GetSameLenString(item.Value.TotalMilliseconds, 10, false) }毫秒     ";
                    str += $"
    ";
                }
                sb.Append(str + "
    
    ");
    
    
                //方法-总耗时
                str = "";
                str += $"所有方法-耗时:{TotalMilliseconds}毫秒    ";
                str += $"{TotalMilliseconds / 1000}秒    ";
                str += $"{(TotalMilliseconds / 1000 / 60).ToString("f2")}分钟    ";
                str += $"当前时间:{DateTime.Now}    ";
                sb.Insert(0, str + "
    
    ");
    
    
                //方法每次-耗时
                if (ShowDetailRecord)
                {
                    for (int i = 0; i < list.Count; i++)
                    {
                        Console.WriteLine($"处理数据-当前行:{list.Count - i}");
                        var item = list[i];
    
                        //数据过滤                   
                        if (IsFilter && !list_Show_Method.Contains(item.MethodName))
                        {
                            continue;
                        }
    
                        sb.Append($"命名空间:{GetSameLenString(item.NameSpaceName, 40)}     ");
                        sb.Append($"类名:{GetSameLenString(item.ClassName, 30)}     ");
                        sb.Append($"方法:{GetSameLenString(item.MethodName + item.ParameterTypes, 80)}     ");
                        sb.Append($"次数:{GetSameLenString(item.ExecuteNumber, 10)}     ");
                        sb.Append($"耗时:{GetSameLenString(item.TotalMilliseconds, 10, false) }毫秒     ");
                        sb.Append($"参数:{GetSameLenString(item.Parameters, 50)}     ");
                        sb.Append($"
    ");
                    }
                }
    
                //计算日志-耗时
                sb.Insert(0, $"计算日志-耗时:{DateTime.Now.Subtract(beforDT).TotalSeconds.ToString("#0.00000")}秒 
    
    ");
    
    
                System.IO.File.WriteAllText($"LOG_{DateTime.Now.ToString("yyyyMMddHHmmssfff")}.txt", sb.ToString());
                Console.WriteLine("完成!");
            }
    
        }
    View Code

    测试类:

        /// <summary>
        /// 测试类1
        /// </summary>
        public class Class5_test1
        {
            public virtual void test1()
            {
                System.Threading.Thread.Sleep(1000 * 1);
                int num = 0;
                for (int i = 0; i < 10000; i++)
                {
                    num += 1;
                }
                test1(1);
                test1(1, 2);
                test1(1, "");
            }
            public virtual void test1(int i) { }
            public virtual void test1(int i, int j) { }
            public virtual void test1(int i, string j) { }
        }    
    View Code

    入口:

        class Class5
        {
            static void Main(string[] args)
            {
                ProxyGenerator generator = new ProxyGenerator();//代理
                CallingLogInterceptor interceptor = new CallingLogInterceptor();//定义 拦截器
                Class5_test1 entity = generator.CreateClassProxy<Class5_test1>(interceptor);
                //SensorRecordService entity = generator.CreateClassProxy<SensorRecordService>(interceptor);
    
                
                DateTime beforDT1 = DateTime.Now;//开始时间     
                try
                {
                    entity.test1();
                    //entity.DealWithSensorRecord(74619, 174619);
                    //int start = Convert.ToInt32(GetAppSetting("start_Id"));
                    //int end = Convert.ToInt32(GetAppSetting("end_Id"));
                    //for (int i = start; i < end;)
                    //{
                    //    int start_Id = i;
                    //    i = i + 10000;
                    //    int end_Id = i > end ? end : i;
                    //    Console.WriteLine($"开始计算:start_Id:{start_Id} end_Id:{end_Id}");
                    //    entity.DealWithSensorRecord(start_Id, end_Id);
                    //}
    
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                }
                MethodOperationInfo.Show();
    
    
    
                TimeSpan ts = DateTime.Now.Subtract(beforDT1);
                string str = $"总共耗时:{ts.TotalSeconds.ToString()}秒  或  {ts.TotalMinutes.ToString("f3")}分";
                System.IO.File.AppendAllText("1.txt", $"{str}
    
    ");
    
                Console.WriteLine(str);
                Console.WriteLine("操作完成!");
                Console.ReadLine();
            }
    
            /// <summary>
            /// 获取 配置文件信息
            /// </summary>
            /// <param name="key"></param>
            /// <returns></returns>
            public static string GetAppSetting(string key)
            {
                return ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None).AppSettings.Settings[key].Value;
            }
        }
    View Code

    会往Debug写入一个日志文件。

    预览效果1:

     预览效果2:

    预览效果3:(删掉了命名空间和类名)

  • 相关阅读:
    程序员推荐书籍汇总
    mysql优化之表建设
    curl_setopt用此函数设置上传文件请求的兼容性调整
    VIM使用总结
    HDU3709 Balanced Number (数位dp)
    POJ2796 单调队列
    HDU 4870 Rating (2014 Multi-University Training Contest 1)
    HDU 4869 Turn the pokers (2014 Multi-University Training Contest 1)
    HDU 4864 (2014 Multi-University Training Contest 1 )
    Go Deeper(2010成都现场赛题)(2-sat)
  • 原文地址:https://www.cnblogs.com/guxingy/p/10142242.html
Copyright © 2020-2023  润新知