我有兴趣衡量执行特定方法所花费的时间。
我当时想使用“自定义属性”来实现此目的非常方便,而不是使用乱码方法来启动/停止秒表并发送至记录器。如果我可以使用属性来修饰所讨论的方法,那将真的很方便!
根据本文,我能够创建一个自定义属性: https://docs.microsoft.com/en-us/dotnet/standard/attributes/writing-custom-attributes
像这样:
public class MonitorExecutionTime : Attribute
{
private Stopwatch measureExecution;
// Start measuring on instantiation
public MonitorExecutionTime()
{
measureExecution = new Stopwatch();
measureExecution.Start();
}
// how do I hook into end invoke?
public MethodHasEnded()
{
measureExecution.Stop();
TimeSpan timeSpan = measureExecution.Elapsed;
Console.WriteLine("Time: {0}h {1}m {2}s {3}ms", timeSpan.Hours, timeSpan.Minutes, timeSpan.Seconds, timeSpan.Milliseconds);
}
}
但是我不确定如何“捕获”正在执行和结束的执行点,以便启动秒表和停止秒表(以测量时间并记录时间)。
有人在.net核心应用中采用这种方法吗?预先感谢您的任何指点!
答案 0 :(得分:1)
.NET中的属性不是包装器,因此您不能以这种方式使用它们。 您必须使用方法调用包装,例如:
public class Service : IService
{
public void Exec() {
Wrap("Method Exec", () => {
// do something usefull
});
}
private void Wrap(string message, Action action)
{
var watch = Stopwatch.StartNew();
try
{
action();
}
finally
{
watch.Stop();
Console.WriteLine($"{message} executed in {watch.ElapsedMilliseconds} ms");
}
}
}
如果要包装类或接口的所有方法,则应查看面向方面的编程,例如,在本文中:https://www.c-sharpcorner.com/article/aspect-oriented-programming-in-c-sharp-using-dispatchproxy/
答案 1 :(得分:1)
在运行时不调用属性。但是您可以使用Fody之类的库来进行程序集编织-在将程序集编译为标有您的自定义属性的方法后自动添加代码。
事实上,已经有一个您想要实现的实现-Method Timer
这是它的工作方式(从文档中复制/粘贴)。您的代码:
public class MyClass
{
[Time]
public void MyMethod()
{
//Some code u are curious how long it takes
Console.WriteLine("Hello");
}
}
实际编译成最终装配的东西
public class MyClass
{
public void MyMethod()
{
var stopwatch = Stopwatch.StartNew();
try
{
//Some code u are curious how long it takes
Console.WriteLine("Hello");
}
finally
{
stopwatch.Stop();
Trace.WriteLine("MyClass.MyMethod " + stopwatch.ElapsedMilliseconds + "ms");
}
}
}
您可以编写自定义拦截器代码来避免使用Trace.WriteLine并按照所需方式进行记录。
答案 2 :(得分:0)
@ Igore-goyda-您的帖子向我发送了我需要的信息。总结为其他人-有两种方法可以拦截方法并运行一些自定义处理。通过代理或使用IL重写器。
我发现这篇文章擅长于解释:http://jeffbelback.me/posts/2015/06/01/principles-of-aop/
我认为Proxy方法最适合我(不喜欢编译后修改我的代码的想法),并且能够在本文之后使用Autofac实现合适的解决方案: https://nearsoft.com/blog/aspect-oriented-programming-aop-in-net-core-and-c-using-autofac-and-dynamicproxy/
Autofac文档也帮助了我: https://autofaccn.readthedocs.io/en/latest/advanced/interceptors.html?highlight=proxy