C# 时间泛型函数的包装器

C# 时间泛型函数的包装器,c#,time,wrapper,C#,Time,Wrapper,我正在写一些代码来生成程序映射。 有些步骤比其他步骤耗时更长,我正在对构建的每个部分进行计时,以查看瓶颈在哪里,并让用户知道程序没有在瓶颈上暂停 目前,我有很多代码如下所示: Console.Write("Creating tiles"); var watch = System.Diagnostics.Stopwatch.StartNew(); CreateTiles(); //key mapgen function watch.Stop(); Console.WriteLine("...

我正在写一些代码来生成程序映射。 有些步骤比其他步骤耗时更长,我正在对构建的每个部分进行计时,以查看瓶颈在哪里,并让用户知道程序没有在瓶颈上暂停

目前,我有很多代码如下所示:

Console.Write("Creating tiles");
var watch = System.Diagnostics.Stopwatch.StartNew();
CreateTiles();    //key mapgen function
watch.Stop();
Console.WriteLine("... finished in: {0} s", watch.ElapsedMilliseconds/1000d);

Console.Write("Calculating tile elevations");
var watch = System.Diagnostics.Stopwatch.StartNew();
CalculateTileElevations();    //key mapgen function
watch.Stop();
Console.WriteLine("... finished in: {0} s", watch.ElapsedMilliseconds/1000d);
//etc
public void ExecuteTimedFunction(Action action, string name)
{
    Console.Write(name);
    var watch = Stopwatch.StartNew();
    action();
    watch.Stop();
    Console.WriteLine("... finished in: {0} s", watch.ElapsedMilliseconds/1000d);
}
我的问题是,有没有一种方法可以重构它,使其看起来更像以下内容:

ExecuteTimedFunction(CreateTiles(), "Creating tiles");
ExecuteTimedFunction(CalculateTileElevations(), "Calculating tile elevations");

void ExecuteTimedFunction(Func genericFunction, String logMsg)
{
    Console.Write(logMsg);
    var watch = System.Diagnostics.Stopwatch.StartNew();
    genericFunction();    
    watch.Stop();
    Console.WriteLine("... finished in: {0} s", watch.ElapsedMilliseconds/1000d);
}
警告:所有函数的返回类型都是无效的,因为它们都操作一个主分幅列表,但并非所有函数都有相同数量的输入参数,尽管大多数函数都有0个参数,因此这种情况下的解决方案仍然有用

您的ExecuteMedidFunction方法如下所示:

Console.Write("Creating tiles");
var watch = System.Diagnostics.Stopwatch.StartNew();
CreateTiles();    //key mapgen function
watch.Stop();
Console.WriteLine("... finished in: {0} s", watch.ElapsedMilliseconds/1000d);

Console.Write("Calculating tile elevations");
var watch = System.Diagnostics.Stopwatch.StartNew();
CalculateTileElevations();    //key mapgen function
watch.Stop();
Console.WriteLine("... finished in: {0} s", watch.ElapsedMilliseconds/1000d);
//etc
public void ExecuteTimedFunction(Action action, string name)
{
    Console.Write(name);
    var watch = Stopwatch.StartNew();
    action();
    watch.Stop();
    Console.WriteLine("... finished in: {0} s", watch.ElapsedMilliseconds/1000d);
}
然后,您可以通过以下任一方式调用它:

ExecuteTimedFunction(MyFunctionWithNoParams, "MyFunc");
ExecuteTimedFunction(() => MyFuncWithParams(p1, p2), "MyFunc2");

您还可以通过将其更改为以下内容来访问被调用的方法详细信息以进行日志记录:

Console.WriteLine($"{action.Method.Name} finished in: {watch.ElapsedMilliseconds / 1000d} s");

如果将genericFunction的类型更改为Action,它应该可以工作。然后您可以像ExecuteTimedFunctionCreateTiles一样调用它,创建tiles;太棒了,这正是我想要的。有人能推荐一个关于行动和类似活动的介绍性资料吗?可能是资料来源:MSDN并不总是对新手最友好的地方,但我会尝试一下:这很酷,但有些函数有复杂的子例程,它们要么自己计时,要么显示完成百分比等,所以我希望在方法实际运行之前打印“function start”