使用AOP的方式监测方法执行耗时
在一些对系统中,往往可能需要对一些核心业务做相应的监测。如:记录调用参数,返回值,方法执行耗时等等。如果直接在方法的前后加入代码,如下:
public int F(int a, string s)
{
var now = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:fff");
var sw = Stopwatch.StartNew(); int ret = ; long second = sw.ElapsedMilliseconds;
var end = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:fff");
log.Write(now, end, second, a, s, ret);
}
这样有以下几点问题:
1.将业务逻辑和方法执行监测混在一起。
2.会有大量重复代码,哪怕你做了一层封装,也依然不够优雅。
由于有了以上的问题,我们会思考,如果可以将方法的调用过程抽象出来,在方法开始调用和方法调用结束时,植入代码,这样就可以很好的解决我们的问题。
.NET中,我们可以通过RealProxy来实现我们想要的功能。RealProxy(https://msdn.microsoft.com/zh-cn/library/vstudio/system.runtime.remoting.proxies.proxyattribute(v=vs.100).aspx)MSDN的定义。在Invoke方法中,可以拦截方法的执行,那么我们就可以在方法的执行前后做一些事情啦。
那么怎么更优雅的应用在方法上呢,我们可以用ProxyAttribute使用Attribute的方式。可以在对象初始化的时候(new关键字)创建相应的代理类。具体代码如下:
/// <summary>
/// 标记要性能监测的类
/// </summary>
[AttributeUsage(AttributeTargets.Class)]
public class MonitorServiceAttribute : ProxyAttribute
{
public override MarshalByRefObject CreateInstance(Type serverType)
{
var instance = base.CreateInstance(serverType);
var proxy = new InjectProxy(serverType, instance).GetTransparentProxy();
return proxy as MarshalByRefObject;
} }
InjectProxy代码如下:
public override IMessage Invoke(IMessage msg)
{
var call = (IMethodCallMessage) msg;
var ctr = call as IConstructionCallMessage; IMethodReturnMessage back;
if (ctr != null)
{
RealProxy defaultProxy = RemotingServices.GetRealProxy(_instance);
defaultProxy.InitializeServerObject(ctr);
back = EnterpriseServicesHelper.CreateConstructionReturnMessage(ctr,
(MarshalByRefObject) GetTransparentProxy());
}
else
{
var now = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:fff");
var sw = Stopwatch.StartNew();
back = RemotingServices.ExecuteMessage(_instance, call);
long second = sw.ElapsedMilliseconds;
var attr = MethodAttributeCache.GetAttribute<MonitorMethodAttribute>(_instance.GetType().TypeHandle,
call.MethodBase); if (attr != null)
{
attr.Value = second.ToString();
attr.ExecuteTime = now;
Queue.Enqueue(Mapper(attr));
}
}
return back;
}
我在这里只记录了方法执行耗时,可以从call里拿到参数,从back里获取到返回值。
具体调用地方如下,注意类需要继承ContextBoundObject:
internal class Program
{
private static void Main(string[] args)
{
var t = new Test();
t.F(,"aaa");
}
} [MonitorService]
internal class Test : ContextBoundObject
{
[MonitorMethod("A")]
public int F(int a,string s)
{
return ;
} }
使用AOP的方式监测方法执行耗时的更多相关文章
- .Net中的AOP系列之《方法执行前后——边界切面》
返回<.Net中的AOP>系列学习总目录 本篇目录 边界切面 PostSharp方法边界 方法边界 VS 方法拦截 ASP.NET HttpModule边界 真实案例--检查是否为移动端用 ...
- C#监测方法执行效率
System.Diagnostics.Stopwatch watch = new Stopwatch(); watch.Start(); // 开始监视代码运行时间 //需要监测的代码 dothing ...
- .NET/C# 在代码中测量代码执行耗时的建议(比较系统性能计数器和系统时间)
我们有很多种方法评估一个方法的执行耗时,比如使用性能分析工具,使用基准性能测试.不过传统的在代码中编写计时的方式依然有效,因为它可以生产环境或用户端得到真实环境下的执行耗时. 如果你希望在 .NET/ ...
- 基于Java Agent的premain方式实现方法耗时监控(转),为了找到结论执行:premain在jvm启动的时候执行,所有方法前,会执行MyAgent的premain方法
Java Agent是依附于java应用程序并能对其字节码做相关更改的一项技术,它也是一个Jar包,但并不能独立运行,有点像寄生虫的感觉.当今的许多开源工具尤其是监控和诊断工具,很多都是基于Java ...
- C#代码执行耗时计算,此处是监测的mvc控制器方法
版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/u011511086/article/details/78710980using System;usi ...
- 使用spring声明式事务,spring使用AOP来支持声明式事务,会根据事务属性,自动在方法调用之前决定是否开启一个事务,并在方法执行之后决定事务提交或回滚事务。
使用spring声明式事务,spring使用AOP来支持声明式事务,会根据事务属性,自动在方法调用之前决定是否开启一个事务,并在方法执行之后决定事务提交或回滚事务.
- SpringBoot 中aop整合方法执行日志
今天事情不多, 处理完手中的事边想着捣鼓一下AOP, 着手开始写才发现, 多久不用, 自己已经忘得差不多了, 捣鼓半天之后, 慢慢整出这个小demo,以便于以后查阅回顾 1 .先创建一个注解, 用来作 ...
- Golang记录、计算函数执行耗时、运行时间的一个简单方法
// 写超时警告日志 通用方法 func TimeoutWarning(tag, detailed string, start time.Time, timeLimit float64) { ...
- golang 记录函数执行耗时的一个简单方法。
先写一个公共函数, 比如在 common 包下有这么一个方法: // 写超时警告日志 通用方法 func TimeoutWarning(tag, detailed string, start time ...
随机推荐
- ruby, gem install 出现网络错误
gem sources #查看目前的源 gem sources --remove https://rubygems.org/ gem sources -a https://ruby.taobao.or ...
- Mysql基于GTID主从复制
Mysql5.6基于GTID全局事务的复制 什么是GTID? GTID(Global Transaction Identifiers)是全局事务标识 当使用GTIDS时,在主上提交的每一个事务都会 ...
- jQuery常用的查找Dom元素方法
废话不多说,先来个总结,然后下面是demo 一. 同级节点之间的检索(检索深度N=0) next()是在兄弟节点中,往后匹配; prev()是在兄弟节点中,往前匹配. 二. 父级/子级节点的检索(检索 ...
- Oracle case 关键字的使用
select e.salary, --case 语句开始 case then salary else salary end new_salary --case 语句结束,可见也和存储过程等结束方式一样 ...
- SpringMVC轻松学习-其他常用(四)
Spring MVC 3.0 深入 核心原理 1. 用户发送请求给服务器.url:user.do 2. 服务器收到请求.发现DispatchServlet可以处理.于是调用Disp ...
- openstack controller ha测试环境搭建记录(九)——配置nova(计算节点)
编辑所有节点的/etc/hosts:10.0.0.14 controller110.0.0.12 controller210.0.0.13 controller310.0.0.10 myvip10.0 ...
- HYBControllerTransitions中文文档
中文文档 HYBControllerTransitions是自定义围场动画API封装类库,使用简便.使用者不需要了解太多转场动画知识,即可轻松接入项目使用. 这是一个给开发者们提供自定义push.po ...
- [Unity]蓝鸥Untiy-RPC-Sample
蓝鸥Untiy-RPC-Sample 使用UnityEngine中的NetWork创建的服务器类 LO_GameServer.cs ** 通过该工具类能够在Unity程序中快速的创建一个游戏房间服务器 ...
- laravel安装excel功能
原文安装链接:https://github.com/Maatwebsite/Laravel-Excel 代码如下: if ($rows = DB::connection('glist')->ta ...
- 《C程序设计语言》读书笔记----习题1-21
题目就不写了,大概意思就是:尽量用制表符'\t'替换掉字符串中的空格. 同学们需要注意的是,打印一个制表符'\t',其所占长度不是固定的. 这里要理解“制表符”和“制表符终止位”.“制表符”的作用是使 ...