bojank
bojank

Reputation: 405

Measuring execution time of async code snippets

I am having trouble with my function for measuring execution time of async code snippets, so I created a console app for easier testing. I was trying to see if the time required for downloading a 200MB file corresponds to the output of the program. However, the app stops executing right after the first command of the code snippet finishes with the output "22 ms". Any ideas why this is happening?

In my real app with a GUI, which is inherently multi-threaded, the measured times were also unrealistic. I tried inserting "Task.Delay" calls into the snippets and it seemed to have no impact on the measured values.

For the sake of brevity, I shortened the code from the real app. Any ideas why this is not working? Alternative ideas on how to measure the time execution of async code snippets?

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");
    }
}

Upvotes: 4

Views: 4249

Answers (1)

Connell.O'Donnell
Connell.O'Donnell

Reputation: 3703

The problem seems to be with the line

await Task.Run(measuredAction);

Try this instead

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");
    }

Upvotes: 4

Related Questions