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

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

把自己的文章的代码复制了下来,稍微改了一下,运行看了一下效果,然后仔细一看,计算的总时间不对,如下图:

上一篇文章的地址:https://www.cnblogs.com/guxingy/p/10142242.html

改了几个地方:

    /// <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;

            Console.WriteLine($"方法名称:{invocation.Method.Name}" );
            Console.WriteLine($"开始时间:{dt.ToString("yyyy-MM-dd HH:mm:ss fff")}");
            Console.WriteLine($"结束时间:{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff")}");
            Console.WriteLine($"所用时间:{ts.TotalSeconds}");

            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>
    /// 测试类1
    /// </summary>
    public class Class5_test1
    {
        public virtual void test1()
        {
            test4();
            test3();
            test2();
        }
        public virtual void test2()
        {
            System.Threading.Thread.Sleep(1000);
        }
        public virtual void test3()
        {
            System.Threading.Thread.Sleep(2000);
        }
        public virtual void test4()
        {
            System.Threading.Thread.Sleep(3000);
        }
    }

    public class MyProxyGenerator
    {
        /// <summary>
        /// 创建一个代理对象
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public static T CreateProxy<T>() where T : class
        {
            ProxyGenerator generator = new ProxyGenerator();//代理
            CallingLogInterceptor interceptor = new CallingLogInterceptor();//定义 拦截器
            T entity = generator.CreateClassProxy<T>(interceptor);
            return entity;
        }
    }

    public class Class2
    {
        public static void test1()
        {
            Class5_test1 entity = MyProxyGenerator.CreateProxy<Class5_test1>();
            entity.test1();
            MethodOperationInfo.ShowContainsDetail();

            Console.Read();
        }
    }

说明:所有的测试,只是修改了一下Class5_test1 这个类给

测试1

    /// <summary>
    /// 测试类1
    /// </summary>
    public class Class5_test1
    {
        public virtual void test1()
        {
            test2();
            test3();
            test4();
        }
        public virtual void test2()
        {
            System.Threading.Thread.Sleep(1000);
        }
        public virtual void test3()
        {
            System.Threading.Thread.Sleep(2000);
        }
        public virtual void test4()
        {
            System.Threading.Thread.Sleep(3000);
        }
    }

问题:这里test1调用了test2、test3、test4,那么执行test1所用时间,应该是test2、test3、test4所用时间的总和,正确所用时间至少应该是6秒(1+2+3),结果这里输出的是3秒多,肯定不对。

测试2

    /// <summary>
    /// 测试类1
    /// </summary>
    public class Class5_test1
    {
        public virtual void test1()
        {
            test4();
            test3();
            test2();
        }
        public virtual void test2()
        {
            System.Threading.Thread.Sleep(1000);
        }
        public virtual void test3()
        {
            System.Threading.Thread.Sleep(2000);
        }
        public virtual void test4()
        {
            System.Threading.Thread.Sleep(3000);
        }
    }

问题:这里的test1方法的所用时间是1秒多,更不对了。

结论:

  测试1 和 测试2 的区别,只是在test1里面改变了test2、test3、test4的执行顺序,结果时间却迥然不同,更奇怪的是,test1的所用时间,更是莫名的接近调用的倒数第二个方法。

  测试1里面,test1的所用时间,很接近test4。

  测试2里面,test1的所用时间,很接近test2。

  反正就是所用时间,很接近 方法体里面 最后一个 调用的方法,原因找到了再补充,了解一下动态代理的原理或许就知道了,也获取是自己写错了,估计是第一种可能

乘着自己好奇,又测试了一下,看下面哦

    /// <summary>
    /// 测试类1
    /// </summary>
    public class Class5_test1
    {
        public virtual void test1()
        {
            Console.WriteLine("开始执行test1");
            test4();
            test3();
            test2();
            Console.WriteLine("执行完成test1");
        }
        public virtual void test2()
        {
            System.Threading.Thread.Sleep(1000);
        }
        public virtual void test3()
        {
            System.Threading.Thread.Sleep(2000);
        }
        public virtual void test4()
        {
            System.Threading.Thread.Sleep(3000);
        }
    }

主要是是在,test1方法里面添加了方法的执行情况, 输出 开始执行 和 执行完成。

原文地址:https://www.cnblogs.com/guxingy/p/11063298.html

时间: 2024-10-10 20:49:05

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

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

在ORACLE数据库应用调优中,一个SQL的执行次数/频率也是常常需要关注的,因为某个SQL执行太频繁,要么是由于应用设计有缺陷,需要在业务逻辑上做出优化处理,要么是业务特殊性所导致.如果执行频繁的SQL,往往容易遭遇一些并发性的问题. 那么如何查看ORACLE数据库某个SQL的执行频率/次数呢? 有哪些途径方法呢? 方法1: 通过查询V$SQLAREA或V$SQL的EXECUTIONS来查看SQL的执行次数,但是这个值的有效性需要结合FIRST_LOAD_TIME来判断.因为V$SQLAREA

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

原文:PLSQL_监控有些SQL的执行次数和频率 2014-12-25 Created By 鲍新建 一.摘要 在ORACLE数据库应用调优中,一个SQL的执行次数/频率也是常常需要关注的,因为某个SQL执行太频繁,要么是由于应用设计有缺陷,需要在业务逻辑上做出优化处理,要么是业务特殊性所导致. 如果执行频繁的SQL,往往容易遭遇一些并发性的问题. 那么如何查看ORACLE数据库某个SQL的执行频率/次数,潇湘隐者同学整理如下,借花献佛了 :) 方法1: 通过查询V$SQLAREA或V$SQL的

Js和jQuery的文档就绪函数以及执行次数

Js和jQuery的文档就绪函数以及执行次数 1:JS文档就绪函数: 采用onload方法: 2:jQuery文档就绪函数: 方法一:采用ready方法 方法二: 通过上面的两种方法可看出:利用方法二比较精简,方法二应用广泛 3. JS文档就绪函数的执行次数: ---js的文档就绪函数不能定义多个.如果定义多个,最后定义的文档就绪函数会覆盖之前的. 例如: 像上面这样,函数定义两个或者两个以上的时候,最后弹出的结果只有"2",因为后面定义的文档就绪函数会覆盖前面的. 4.jQuery文

使用AOP拦截器获取一次请求流经方法的调用次数和调用耗时

引语 作为工程师,不能仅仅满足于实现了现有的功能逻辑,还必须深入认识系统.一次请求,流经了哪些方法,调用了多少次DB操作,多少次API操作,多少次IO操作,多少CPU操作,各耗时多少 ? 开发者必须知道这些运行时数据,才能对系统的运行有更深入的理解,更好滴提升系统的性能和稳定性. 完成一次订单导出任务,实际上是一个比较复杂的过程:需要访问ES 来查询订单,调用 API 及访问 Hbase 获取订单详情数据,写入和上传报表文件,更新数据库,上报日志数据等:在大流量导出的情形下,采用批量并发策略,多

initMethod 和 afterPropertiesSet 以及 AwareMethod方法的执行时机

在spring开发中,我们定义bean 经常会需要用到beanFactory对象,这就需要实现BeanFactoryAware这种类型的接口,它有一个setBeanFactory方法   在xml中配置bean 的时候,我们也可以指定initMethod方法   在bean类定义的时候可以实现InitializingBean,提供一个afterPropertiesSet方法的实现     以上者3中情况我们经常用到,下面来分析一下spring是如何处理这3种情况的,他们的调用时机是怎么样的?  

C# 给某个方法设定执行超时时间 C#函数运行超时则终止执行(任意参数类型及参数个数通用版)

在某些情况下(例如通过网络访问数据),常常不希望程序卡住而占用太多时间以至于造成界面假死. 在这时.我们可以通过Thread.Thread + Invoke(UI)或者是 delegate.BeginInvoke 来避免界面假死, 但是这样做时,某些代码或者是某个方法的执行超时的时间还是无法操控的.那么我们又是否有一种比较通用的方法.来设定某一个方法的执行超时的时间,让该其一旦超过指定时间则跳出指定方法.进而继续向下执行呢? 答案当然是肯定的. delegate.BeginInvoke可以实现代

Junit4学习笔记--方法的执行顺序

package com.lt.Demo.TestDemo; import java.util.Arrays; import java.util.Collection; import org.junit.After; import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; import org.junit.runner.RunWith; im

java循环练习:由输入的值决定循环的执行次数,循环变量默认从1开始

package practiceGO; import java.util.Scanner; /*   3.由输入的值决定循环的执行次数,循环变量默认从1开始  */ public class Cto { public static void main(String[] args) { Scanner sc = new Scanner(System .in); System.out.println("请输入循环次数:"); int time = sc.nextInt(); for(int

Android中的Sqlite中的onCreate方法和onUpgrade方法的执行时机

今天在做数据库升级的时候,遇到一个问题,就是onCreate方法和onUpgrade方法的执行时机的问题,这个当时在操作的时候,没有弄清楚,很是迷糊,所以写代码的时候出现了很多的问题,所以没办法就去扒源代码看了.不过在此之前我讲解过一篇关于数据库升级的文章,但是那里没有详细的讲解一下这两个方法的执行时机,所以这里就在单独说一下 关于数据库升级的文章:http://blog.csdn.net/jiangwei0910410003/article/details/39670813 不多说,下面直接进