2017-02-17 5 views
2

У меня возникают проблемы с моей функцией для измерения времени выполнения асинхронных фрагментов кода, поэтому я создал консольное приложение для более легкого тестирования. Я пытался выяснить, соответствует ли время, требуемое для загрузки файла в 200 МБ выходному сигналу программы. Однако приложение прекращает выполнение сразу после того, как первая команда фрагмента кода заканчивается с выходом «22 мс». Есть идеи, почему это происходит?Измерение времени выполнения асинхронных фрагментов кода

В моем реальном приложении с графическим интерфейсом, который по своей сути является многопоточным, измеренные времена также нереалистичны. Я попытался вставить «Task.Delay» в фрагменты и, похоже, не повлиял на измеренные значения.

Для краткости я сократил код из реального приложения. Любые идеи, почему это не работает? Альтернативные идеи о том, как измерять время выполнения асинхронных фрагментов кода?

class Program 
{ 
    static void Main(string[] args) 
    { 
     MainAsync().GetAwaiter().GetResult(); 
    } 

    private static async Task MainAsync() 
    { 
     var httpClient = new HttpClient(); 

     await MeasureExecutionTimeAsync(
      async() => { 
       // download a 200MB file 
       var response = await httpClient.GetAsync("http://web4host.net/200MB.zip"); 

       // this never gets executed 
       var array = await response.Content.ReadAsByteArrayAsync(); 
       File.WriteAllBytes("C:/mytmp/bytefile.xxx", array); 
      } 
     ); 
    } 

    private static async Task MeasureExecutionTimeAsync(Action measuredAction) 
    { 
     var stopwatch = new Stopwatch(); 
     stopwatch.Start(); 

     await Task.Run(measuredAction); 

     stopwatch.Stop(); 

     Console.WriteLine(stopwatch.ElapsedMilliseconds + " ms"); 
    } 
} 
+1

Это является довольно распространенным "' Task' в 'Task'" проблемы. То, как у вас есть вещи в данный момент, вы не измеряете время выполнения внутренней задачи, а время для выполнения внешней задачи (которая только создает внутреннюю задачу), и это, конечно, почти ноль , – sellotape

+0

Основная проблема связана с использованием 'async void'. Передавая «async» лямбда параметру делегата «Action», этот код инструктирует компилятор написать метод «async void». –

ответ

1

Проблема, кажется, с линией

await Task.Run(measuredAction); 

Попробуйте вместо

private static async Task MainAsync() 
    { 
     var httpClient = new HttpClient(); 

     Func<Task> action = async() => 
     { 
      var response = await httpClient.GetAsync("http://web4host.net/200MB.zip").ConfigureAwait(false); 

      // this never gets executed 
      var array = await response.Content.ReadAsByteArrayAsync(); 
      File.WriteAllBytes("C:/mytmp/bytefile.xxx", array); 
      return; 
     }; 

     await MeasureExecutionTimeAsync(action); 
    } 

    private static async Task MeasureExecutionTimeAsync(Func<Task> measuredAction) 
    { 
     var stopwatch = new Stopwatch(); 
     stopwatch.Start(); 

     await measuredAction.Invoke(); 

     stopwatch.Stop(); 

     Console.WriteLine(stopwatch.ElapsedMilliseconds + " ms"); 
    } 
+5

Или просто 'await measuredAction();' вместо использования 'Invoke()'. – sellotape