时间泛型函数的包装器

本文关键字:包装 函数 泛型 时间 | 更新日期: 2023-09-27 18:06:54

我正在编写一些代码来生成过程映射。有些步骤比其他步骤花费的时间要长得多,我对构建的每个部分进行计时,以查看瓶颈在哪里,并让用户知道程序没有在它们上停滞。

现在我有很多代码看起来像这样:

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

我的问题是,是否有一种方法可以重构它,使其看起来更像以下内容:

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);
}

注意:所有函数的返回类型都是void,因为它们都操作一个tile的主列表,但并不是所有函数都有相同数量的输入参数(尽管大多数函数有0个参数,所以这种情况的解决方案仍然是有用的)

时间泛型函数的包装器

您的ExecuteTimedFunction方法看起来像这样:

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");