2014-12-10 2 views
1

Как рассчитать время, например, 3 метода, но это только первый и последний методы, в которых мне нужно время. Мне не нужно время по среднему методу. Пример. МетодOne принимает 200 мс, MethodTwo принимает 500 мс, MethodThree принимает 300 мс. Общее время: 1000 мс. Но это должно быть 1000 мс - 500 мс (MethodTwo) = 500 мс.Как рассчитать время для методов в C#

Есть ли программное обеспечение, которое может это сделать? Или как я могу изменить свой код для работы?

static void Main(string[] args) 
{ 
    Console.WriteLine("============================"); 
    Console.WriteLine("  Performance   "); 
    Console.WriteLine("============================\n"); 

    Console.WriteLine("Total time: {0}", TimeTaking(MethodOne).TotalMilliseconds.ToString()); 
    Console.ReadKey(); 
} 

static TimeSpan TimeTaking(Action methodName) 
{ 
    Stopwatch stopwatch = Stopwatch.StartNew(); 
    methodName(); 
    stopwatch.Stop(); 
    return stopwatch.Elapsed; 
} 

static void MethodOne() 
{ 
    Thread.Sleep(200); 
    MethodTwo(); 
} 

static void MethodTwo() 
{ 
    // Stop TimeTaking 
    Thread.Sleep(500); 
    MethodThree(); 
} 

static void MethodThree() 
{ 
    // continue TimeTaking 
    Thread.Sleep(300); 
} 
+0

http://msdn.microsoft.com/en-us/library/system.diagnostics.stopwatch%28v=vs.110%29.aspx –

+0

Уточните свой вопрос, пожалуйста. Вам нужно рассчитать каждый из ваших методов работы? Используются ли методы, называемые «один-другой», или ваш подход к расчету? –

+0

Энди, мне нужно рассчитать каждое время работы методов. Я не знаю, как будут называться методы ведьмы. Это может быть 5 методов или это может быть 20 методов в разных проектах. – MHP

ответ

1

Без отдельного профилирующего инструмента, вы должны вручную измерять время с Stopwatch в MethodOne и MethodThree. Невозможно сделать это автоматически.

2

Если безопасность нитей не является проблемой, вы можете поставить Stopwatch вне метода TimeTaking. Это позволяет вам звонить Stop() и Start() в тех местах, где вы хотите (в начале или в конце методов).

В качестве параметра вы, конечно же, можете передать Stopwatch. Или все возвратите int/long, который содержит количество мс, которое потребовалось для запуска. Оба решения довольно уродливы, поскольку он либо добавляет дополнительный параметр, либо заставляет параметры out в случае, если вы хотите вернуть полезное значение.

+0

Я должен быть безопасным потоком. – MHP

1

Есть несколько вариантов здесь ...

Вы используете stopwatch в своих операциях, чтобы узнать продолжительность этих методов. Конечно, это повторяющийся код (даже если вы поместите фактический логический код секундомера в отдельный метод), но может быть достаточно для того, что вам нужно.

Или вы можете использовать AOP with PostSharp, чтобы избежать повторного кода, если вам нужно это поведение во всех ваших методах. Но тогда вы должны организовать свой код немного более модульным (что делает его также более проверяемым):

[LogExecutionTimeAttribute] 
void MethodOne() 
{ 
    Thread.Sleep(200);  
} 

void MethodTwo() 
{  
    Thread.Sleep(500); 
} 

[LogExecutionTimeAttribute] 
void MethodThree() 
{ 
    Thread.Sleep(300); 
} 

void StartFlow() 
{ 
    MethodOne(); 
    MethodTwo(); 
    MethodThree(); 
} 

(Не знаю, почему вам нужно, чтобы быть статическим, следует избегать)

Наконец, но возможно, для вас слишком много, инструменты APM, такие как AppDynamics, также могут это сделать.

+0

Просто из любопытства, не использовал бы решение PostSharp ~ 1000ms для MethodOne? Поскольку он будет записывать только время завершения метода, то есть после MethodTwo и MethodThree. – Chrono

+0

Вы правы, но это побуждает писать код, который менее зависим друг от друга. Вместо методов, вызывающих друг друга, возможно, MethodOne, MethodTwo и MethodThree не могли вызывать друг друга, но вместо этого другой метод будет содержать поток вызова этих методов. Он был бы более модульным, и каждый метод можно было бы проверять независимо друг от друга. –

+0

Он считает, что решение будет APM-инструментами, возможно, AppDynamics. – MHP

0

Я написал этот маленький кусочек кода, чтобы сделать несколько простых измерений:

public class Timer : IDisposable 
    { 
     private readonly Stopwatch _stopwatch; 
     private readonly Action<TimeSpan> _finishedDelegate; 

     private Timer(Action<TimeSpan> finishedDelegate) 
     { 
      if (finishedDelegate == null) 
      { 
       finishedDelegate = timeSpan => Debug.Print("Elapsed time: {0}", timeSpan); 
      } 

      _finishedDelegate = finishedDelegate; 
      _stopwatch = Stopwatch.StartNew(); 
     } 

     public static Timer Start(Action<TimeSpan> finishedDelegate = null) 
     { 
      return new Timer(finishedDelegate); 
     } 

     public void Dispose() 
     { 
      _stopwatch.Stop(); 
      _finishedDelegate.Invoke(_stopwatch.Elapsed); 
     } 
    } 

Используйте как:

using (Timer.Start()) 
{ 
    // Code to be measured here 
} 

Вы можете предоставить делегат в методе Start, чтобы контролировать то, что должно произойти с результат. По умолчанию он выводит время на консоль Debug.