2016-09-14 33 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