原文: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);
}
}

操作日志:

    /// <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 = ; i < count; i++)
{
name += " ";
}
return name; }
else
{
string value = "";
for (int i = ; 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 = ; 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 > ))
{
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 =
};
list.Add(model); //添加到 dictionary
string key = MethodName + ParameterTypes;
if (dic.ContainsKey(key))
{
dic[key].TotalMilliseconds += TotalMilliseconds;
dic[key].ExecuteNumber += ;
}
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 = ;
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 += $"\r\n";
}
sb.Append(str + "\r\n\r\n"); //方法-总耗时
str = "";
str += $"所有方法-耗时:{TotalMilliseconds}毫秒 ";
str += $"{TotalMilliseconds / 1000}秒 ";
str += $"{(TotalMilliseconds / 1000 / 60).ToString("f2")}分钟 ";
str += $"当前时间:{DateTime.Now} ";
sb.Insert(, str + "\r\n\r\n"); //方法每次-耗时
if (ShowDetailRecord)
{
for (int i = ; 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($"\r\n");
}
} //计算日志-耗时
sb.Insert(, $"计算日志-耗时:{DateTime.Now.Subtract(beforDT).TotalSeconds.ToString("#0.00000")}秒 \r\n\r\n"); System.IO.File.WriteAllText($"LOG_{DateTime.Now.ToString("yyyyMMddHHmmssfff")}.txt", sb.ToString());
Console.WriteLine("完成!");
} }

测试类:

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

入口:

    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}\r\n\r\n"); 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;
}
}

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

预览效果1:

预览效果2:

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

C# 监测每个方法的执行次数和占用时间(测试3)的更多相关文章

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

    今天也要做这个功能,就百度一下,结果搜索到了自己的文章.一开始还没注意,当看到里面的一个注释的方法时,一开始还以为自己复制错了代码,结果仔细一看网页的文章,我去,原来是自己写的,写的确实不咋地. 把自 ...

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

    在Nuget引用 Castle.DynamicProxy 和 Newtonsoft.Json 这个 原文:http://www.cnblogs.com/RicCC/archive/2010/03/15 ...

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

    在Nuget引用 Castle.DynamicProxy 和 Newtonsoft.Json 这个 原文:http://www.cnblogs.com/RicCC/archive/2010/03/15 ...

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

    又找到了一个bug 测试的类: public class Class11_1 { public virtual List<int> test2_1(List<tb_SensorRec ...

  5. 事件之onTouch方法的执行过程 及和 onClick执行发生冲突的解决办法

    转载:http://blog.csdn.net/jiangwei0910410003/article/details/17504315#quote 博主推荐: 风萧兮兮易水寒,“天真”一去兮不复还.如 ...

  6. Android中onTouch方法的执行过程以及和onClick执行发生冲突的解决办法

    $*********************************************************************************************$ 博主推荐 ...

  7. ORACLE查看SQL的执行次数/频率

    在ORACLE数据库应用调优中,一个SQL的执行次数/频率也是常常需要关注的,因为某个SQL执行太频繁,要么是由于应用设计有缺陷,需要在业务逻辑上做出优化处理,要么是业务特殊性所导致.如果执行频繁的S ...

  8. PLSQL_查询SQL的执行次数和频率(案例)

    2014-12-25 Created By BaoXinjian

  9. PLSQL_监控有些SQL的执行次数和频率

    原文:PLSQL_监控有些SQL的执行次数和频率 2014-12-25 Created By 鲍新建

随机推荐

  1. 集群中使用chronyc同步时间

    在集群之中,有些服务器之间的时间需要同步,但并不是所有机器可以直接连外网,这时可以用Chrony工具解决. 解决方法是将其中一台设为时间服务器,然后其它服务器和这台时间服务器同步即可.具体步骤如下: ...

  2. three.js学习:纹理Texture之平面纹理

    index.html <!DOCTYPE html> <html lang="en"> <head> <meta charset=&quo ...

  3. 解决Centos7不能联网且ifconfig出现command not found

    在虚拟机中以最小化方式安装centos7,后无法上网,因为centos7默认网卡未激活. 而且在sbin目录中没有ifconfig文件,这是因为centos7已经不使用 ifconfig命令了,已经用 ...

  4. [Unity插件]Lua行为树(三):组合节点Sequence

    Sequence的继承关系如下: Sequence->Composite->ParentTask->Task 上一篇已经实现了简单版本的ParentTask和Task(基于Behav ...

  5. SLD Related Gateway Serivces Unavaliable

    SAP NW 7.4 default switched on the ACL (access control list) in gateway service, so only local acces ...

  6. 制作签名jar放置到前端资源目录下

    给jar包打签名keytool -genkey -keystore myKeystore -alias jwstest查看签名信息jarsigner -keystore myKeystore data ...

  7. jquery小效果:新浪游戏右侧导航菜单 (页面效果)

    偷盗:新浪游戏右侧导航菜单 http://games.sina.com.cn 效果: 随着页面的滚动,左侧页面的内容,和右侧的导航菜单的按钮文字对应: 点击右侧的导航按钮,左侧页面滚动到相应的内容 2 ...

  8. ubuntu 14.04 安装 Apache Thrift 0.10

    1.到官网下载源码压缩文件 https://thrift.apache.org/download 2.安装依赖软件,可以参考 https://thrift.apache.org/docs/instal ...

  9. mysqld服务启动失败, Failed to restart mysqld.service: Unit not found.

    -bash-4.2# service mysqld restart Redirecting to /bin/systemctl restart mysqld.serviceFailed to rest ...

  10. es 测试代码

    测试代码 PUT test/doc/1 { "num": 1.0 } PUT test/doc/2 { "num": 2.0 } POST _scripts/j ...