在一些对系统中,往往可能需要对一些核心业务做相应的监测。如:记录调用参数,返回值,方法执行耗时等等。如果直接在方法的前后加入代码,如下: 

  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的方式监测方法执行耗时的更多相关文章

  1. .Net中的AOP系列之《方法执行前后——边界切面》

    返回<.Net中的AOP>系列学习总目录 本篇目录 边界切面 PostSharp方法边界 方法边界 VS 方法拦截 ASP.NET HttpModule边界 真实案例--检查是否为移动端用 ...

  2. C#监测方法执行效率

    System.Diagnostics.Stopwatch watch = new Stopwatch(); watch.Start(); // 开始监视代码运行时间 //需要监测的代码 dothing ...

  3. .NET/C# 在代码中测量代码执行耗时的建议(比较系统性能计数器和系统时间)

    我们有很多种方法评估一个方法的执行耗时,比如使用性能分析工具,使用基准性能测试.不过传统的在代码中编写计时的方式依然有效,因为它可以生产环境或用户端得到真实环境下的执行耗时. 如果你希望在 .NET/ ...

  4. 基于Java Agent的premain方式实现方法耗时监控(转),为了找到结论执行:premain在jvm启动的时候执行,所有方法前,会执行MyAgent的premain方法

    Java Agent是依附于java应用程序并能对其字节码做相关更改的一项技术,它也是一个Jar包,但并不能独立运行,有点像寄生虫的感觉.当今的许多开源工具尤其是监控和诊断工具,很多都是基于Java ...

  5. C#代码执行耗时计算,此处是监测的mvc控制器方法

    版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/u011511086/article/details/78710980using System;usi ...

  6. 使用spring声明式事务,spring使用AOP来支持声明式事务,会根据事务属性,自动在方法调用之前决定是否开启一个事务,并在方法执行之后决定事务提交或回滚事务。

    使用spring声明式事务,spring使用AOP来支持声明式事务,会根据事务属性,自动在方法调用之前决定是否开启一个事务,并在方法执行之后决定事务提交或回滚事务.

  7. SpringBoot 中aop整合方法执行日志

    今天事情不多, 处理完手中的事边想着捣鼓一下AOP, 着手开始写才发现, 多久不用, 自己已经忘得差不多了, 捣鼓半天之后, 慢慢整出这个小demo,以便于以后查阅回顾 1 .先创建一个注解, 用来作 ...

  8. Golang记录、计算函数执行耗时、运行时间的一个简单方法

    // 写超时警告日志 通用方法   func TimeoutWarning(tag, detailed string, start time.Time, timeLimit float64) {    ...

  9. golang 记录函数执行耗时的一个简单方法。

    先写一个公共函数, 比如在 common 包下有这么一个方法: // 写超时警告日志 通用方法 func TimeoutWarning(tag, detailed string, start time ...

随机推荐

  1. 【poj解题】3663

    排序, 遍历,需要裁减 #include <stdio.h> #include <stdlib.h> #include <string.h> #define MAX ...

  2. 完美解决ie浏览器location.href不刷新页面的问题,进入页面只刷新一次

    /* ie不刷新列表bug */try{ var agent = navigator.userAgent.toLowerCase(); var ieflag = /(msie\s|trident.*r ...

  3. MySQL 批量导入 csv 文件

    注意编码一致性,如:我的数据库是utf-8编码,csv文档的编码也是utf-8. 导入使用 LOAD DATA LOCAL INFILE 详细用法请参看文档或者书籍. mysql  user表结构: ...

  4. iBATIS 3 试用手记 - The FUTURE - ITeye技术网站

    body { font-family: "Microsoft YaHei UI","Microsoft YaHei",SimSun,"Segoe UI ...

  5. 现在都是python 单独开发框架 执行脚本,处理结果,发报告之类的

    现在都是python 单独开发框架 执行脚本,处理结果,发报告之类的

  6. [iOS]C语言知识点系列视频

    C语言知识点系列视频 目录 C语言技术视频-01-变量的定义 C语言技术视频-02-程序分支结构(if...else) C语言技术视频-03-程序分支结构(switch) C语言技术视频-04-程序循 ...

  7. ZOJ 3927 Programming Ability Test

    水题,判断一下加起来是否大于等于80 #include<cstdio> #include<cstring> #include<cmath> #include< ...

  8. 手机端 H5上传头像

    <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...

  9. IOS NSURLRequest 设置 Header

    https://my.oschina.net/wolx/blog/406092 工程中的请求,需要设置Header,请求令牌才访问,NSURLRequest 请求没有直接设置header 的方法,需要 ...

  10. UVA 1386 Cellular Automaton

    矩阵快速幂. 样例是这样构造矩阵的: 矩阵很好构造,但是500*500*500*logk的复杂度显然是无法通过这题的. 其实本题构造出来的矩阵是一个循环矩阵,只需直到第一行或者第一列,即可直到整个矩阵 ...