2016-09-14 35 views
0

我正在编写一些代码来生成过程图。 某些步骤比其他步骤耗时更长,我正在对构建的每个部分进行计时,以查看瓶颈的位置,并让用户知道程序没有停顿。包装时间通用函数

目前,我有很多的代码看起来像这样:

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,因为它们都操纵瓦片的主列表,但并非所有函数都具有相同数量的输入参数(尽管大多数参数具有0个参数,因此对于该情况的解决方案会仍然有用)

+2

如果将'genericFunction'的类型更改为'Action',它应该ķ。然后你可以把它叫做ExecuteTimedFunction(CreateTiles,“Creating tiles”);' – Lee

回答

8

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

太棒了,这个工作正如我所愿。任何人都可以推荐'行动'和类似的介绍性来源? – ms813

+0

可能来源? https://msdn.microsoft.com/en-us/library/018hxwa8(v=vs.110).aspx :) –

+0

MSDN并不总是最适合新事物的新手友好的地方,但我会给它一个去:) – ms813

0

您还可以通过访问调用方法的详细信息记录将其改为类似于:

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

这很酷,但一些功能有复杂的子程序,要么定时自己,要么显示%完成等,所以我想在方法实际运行之前打印'函数启动'打印 – ms813