使用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 ...
随机推荐
- OleDB连接字符串很基础却很重要
--Oracle<add name="HISConnectionString" connectionString=" Server=127.0.0.1;Provid ...
- Ubuntu iptables 设置
在ubuntu中由于不存在 /etc/init.d/iptales文件,所以无法使用service等命令来启动iptables,需要用modprobe命令. 启动iptables modprobe i ...
- Application Fundamentals
Application Fundamentals 署名:译言biAji 链接:http://developer.android.com/guide/topics/fundamentals.html 应 ...
- python+django+bootstrap
python install django 置环境变量,将这个目录添加到系统环境变量中: C:\Python36\Lib\site-packages\django\ cmd下测试: 1.输入pytho ...
- Building Your First EDM
1 文件--新建--项目 控制台应用程序,填写信息,确定: 2 在解决方案管理器中,选中AmyConsoleApp,添加新项, 选择ADO.NET 实体数据模型,添加: 3 在选择模型内容中选择“从数 ...
- XML&AJAX
AJAX: Asynchronous Javascript and XML 1. 客户端触发异步操作 2. 创建新的XMLHttpRequest, 是重要的js对象,通过它提起对服务器端的请求 3. ...
- lpc1788IO口模拟IIC
#ifndef __MYIIC_H_ #define __MYIIC_H_ #include "common.h" #include "delay.h" #in ...
- model first,DB first,code first
code first迁移数据库1.打开程序包管理器控制台2.运行Enable-Migrations,运行之后会生成Migrations文件夹与相应的文件 Configuration.cs3.设置 Au ...
- usb开发
usb开发 USB HID报告及报告描述符简介 LibUSB通过SetReport()请求与USBHID设备通信 libusb开发者指南 USB枚举和HID枚举实例 USB命令 BusHound数据分 ...
- js 回车触发事件
<script type="text/javascript" language=JavaScript > document.onkeydown=function(eve ...