2017-02-17 18 views
2

私は非同期コードスニペットの実行時間を測定する機能に問題があります。そのため、より簡単にテストできるようにコンソールアプリケーションを作成しました。私は、200MBのファイルをダウンロードするのに必要な時間がプログラムの出力に対応しているかどうかを確認しようとしていました。ただし、コードスニペットの最初のコマンドが出力「22 ms」で終了した直後にアプリケーションは実行を停止します。これがなぜ起こっているのか?非同期コードスニペットの実行時間の測定

私の本物のアプリでは、本質的にマルチスレッドのGUIがあり、測定時間も非現実的でした。スニペットに "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

代わりにこれを試してみてくださいラインであると思われます。あなたは現時点では物事を持っていますが、内部タスクの実行時間を測定するのではなく、内部タスクを作成する外部タスクの実行時間を測定しています。もちろんそれはほぼゼロです。 – sellotape

+0

主な問題は、 'async void'の使用によるものです。 'async'ラムダを' Action'デリゲートパラメータに渡すことによって、このコードはコンパイラに 'async void'メソッドを書くよう指示します。 –

答えて

1

問題が

await Task.Run(measuredAction); 

これは問題かなり一般的な "` Task`内の `Task`" である

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

あるいは 'Invoke()'の代わりに単に 'await measuredAction();'を実行してください。 – sellotape

関連する問題