2016-09-14 9 views
0

Я пишу код для создания процедурной карты. Некоторые из этих шагов занимают гораздо больше времени, чем другие, и я определяю каждую часть сборки, чтобы увидеть, где узкие места, и сообщить пользователю, что программа не остановилась на них.Wrapper to time generic function

В настоящее время у меня есть много кода, который выглядит следующим образом:

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,« Создание плит »);' – 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

Удивительно, это работает точно так, как я бы хотел. Может ли кто-нибудь порекомендовать вводный источник на «Action» и тому подобное? – ms813

+0

Возможно, источник? https://msdn.microsoft.com/en-us/library/018hxwa8(v=vs.110).aspx :) –

+0

MSDN не всегда является самым новичком для новых вещей, но я дам ему a go :) – ms813

0

Вы также можете получить доступ к названным деталям методы для регистрации по превращая его в нечто вроде:

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

это классно, но некоторые из функций имеют сложные подпрограммы, которые либо сами по себе, либо показывают% полной и т. д., поэтому я хотел бы, чтобы «функция начала» была напечатана до того, как метод действительно запущен – ms813

 Смежные вопросы

  • Нет связанных вопросов^_^