首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用属性调用函数

使用属性调用函数
EN

Stack Overflow用户
提问于 2015-07-10 17:43:54
回答 1查看 362关注 0票数 1

我有一个函数,它使用秒表的实例通过启动和停止来测量方法的时间。我是否可以在属性中定义该函数,并使用该属性修饰任何给定的方法,以测量该方法的时间?这将降低LOC。我不想使用任何第三方库。

代码语言:javascript
复制
public class AppTrace:BaseModel<AppTrace>
   {
    [DataMember]
    public string Comment;
    [DataMember]
    public string MethodName;
    [DataMember]
    public DateTime StartTimeStamp;
    [DataMember]
    public int Duration;
    [DataMember]
    public int UserObjectId;
    [DataMember]
    public string MachineName;
    [DataMember]
    public int ToolId;
    private System.Diagnostics.Stopwatch stpWatch;


    public AppTrace(string comment,string methodName,int userObjectId   ,string machineName = "",int? toolId=null)
    {
        MethodName = methodName;
        UserObjectId = userObjectId;
        StartTimeStamp = DateTime.UtcNow;
        Comment = comment;
        MachineName = machineName;

        stpWatch = new System.Diagnostics.Stopwatch();
        stpWatch.Start();
    }

    public AppTrace()
    {
    }

    public void CloseTrace()
    {
        this.stpWatch.Stop();
        Duration=Convert.ToInt32( this.stpWatch.ElapsedMilliseconds);
    }

}

如果不是属性,我可以在委托的帮助下做到这一点吗?

EN

回答 1

Stack Overflow用户

发布于 2015-07-10 19:16:51

正如我在评论中所说,这通常是不可能的。您可以使用一些AOP框架,它可以相当成功地处理这类事情。或者编写一些调用实用程序。

在最简单的情况下,您的实用程序可能如下所示:

代码语言:javascript
复制
public static class Invoke 
{
    public static TimeSpan Measure(Action action)
    {
        if (action == null)
        { 
            throw new ArgumentNullException();
        }

        var stopWatch = Stopwatch.StartNew();
        action();
        stopWatch.Stop();

        return stopWatch.Elapsed;
    }  
}

然后,您将能够测量方法调用时间。例如,类Foo将用作测量目标。

代码语言:javascript
复制
// don't use such naming in production code
public class Foo
{
    public void DoWork1()
    {
        // imitating hard computations
        Thread.Sleep(TimeSpan.FromSeconds(5));
    }

    public void DoWork2(int param1) 
    {
        // imitating hard computations
        Thread.Sleep(param1);
    }
}

public static class Program
{
    public static void Main()
    {
        var foo = new Foo();

        // signature of foo.DoWork1 is suitable for Invoke.Measure, 
        //so you can use it as MethodGroup
        var time1 = Invoke.Measure(foo.DoWork1);
        Console.WriteLine("Time for 'DoWork1' is {0}s", time1.TotalSeconds);

        // signature of foo.DoWork2 is not suitable for Invoke.Measure,   
        // so you have to call it inside additional lambda 
        var time2 = Invoke.Measure(() => foo.DoWork2(42));
        Console.WriteLine("Time for 'DoWork2' is {0}s", time2.TotalSeconds);
    }
}

对于返回一些值的方法来说,这会比较困难,但也可以实现。添加助手类Timed<T>,它将包含返回值和操作持续时间。

代码语言:javascript
复制
public class Timed<T>
{
    public readonly TimeSpan Duration;
    public readonly T Result;

    // making constructor private to force static factories usage
    private Timed(T result, TimeSpan duration) 
    {
        Result = result;
        Duration = duration;
    }

    // static factory method instead of constructor, for generic parameter 
    // type inference 
    public static Timed<T> Create(T result, TimeSpan duration) 
    {
        return new Timed<T>(result, duration);
    }
}

那么将需要Invoke.Measure的重载。

代码语言:javascript
复制
public static class Invoke 
{
    // Func<T> instead of Action
    public static Timed<T> Measure(Func<T> func)
    {
        if (func== null)
        { 
            throw new ArgumentNullException();
        }

        var stopWatch = Stopwatch.StartNew();
        var result = func();
        stopWatch.Stop();

        return Timed.Create(result, stopWatch.Elapsed);
    }  
}

顺便说一句,F# REPL#time指令来测量调用时间。您可以从F#调用任何.NET代码。它被集成到Visual Studio中,或者可以从命令行(fsi.exe)调用。我不知道你的实际目标,所以它可能是合适的。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31337614

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档