使用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 ...
随机推荐
- POJ 2728 Desert King 最优比率生成树
Desert King Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 20978 Accepted: 5898 [Des ...
- MySQL 导出命令
mysqldump --no-defaults -u root -p dbname > c:\www\test.sql windows 下使用.
- createNewFile()与createTempFile()的不同
1, File 的 createNewFile() 方法: createNewFile():返回值为 boolean: 方法介绍:当且仅当不存在具有此抽象路径名指定名称的文件时, ...
- 关于 HTML5、Jquery、Phonegap 跨域问题的研究
近期研究Phonegap的相关技术,遇到了服务资源访问的跨域.经过尝试使用服务器端的代理,Phonegap打包后不能够访问到相应资源.在搜索引擎的帮助下,找到了Jquery的jsonp的方式,尝试发现 ...
- IOS开发-UI学习-UIWebView,简单浏览器的制作
制作一个简单的浏览器,包含网址输入框,Search按钮,前进.回退按钮,UIWebView就这几个简单的控件. UITextField:用来输入网址: UIbuttom:实现前进,后退,搜索等功能: ...
- adb报错:The connection to adb is down, and a severe&nbs
我觉得这就像是adb的大姨妈一样,不过处理起来还是很easy滴: 1.报错:BUILD FAILEDD:\workspace\ganji\build.xml:144: The following e ...
- ecshop中ajax的调用原理 1
ecshop中ajax的调用原理 1:首先ecshop是如何定义ajax对象的. ecshop中的ajax对象是在js/transport.js文件中定义的.里面是ajax对象文件.声明了一个va ...
- Max Sum of Rectangle No Larger Than K
Given a non-empty 2D matrix matrix and an integer k, find the max sum of a rectangle in the matrix s ...
- js 回车触发事件
<script type="text/javascript" language=JavaScript > document.onkeydown=function(eve ...
- java判断是否为汉字
java判断是否为汉字 public static boolean isChinese(String str) { String regEx = "[\u4e00-\u9fa5]&quo ...