Search code examples
asynchronoushttpwebrequestbenchmarkingstopwatch

Measuring request time in async requests


I need to run multiple web requests and measure time between request and corresponding response.

Both solutions with existing code using BackgroundWorker and new code using TPL library have following issue I cannot understand:

var watch = Stopwatch.StartNew();

queue.Enqueue(Task.Factory
                    .FromAsync<WebResponse>(webRequest.BeginGetResponse, webRequest.EndGetResponse, null)
                    .ContinueWith(task =>
                    {
                        using (var response = (HttpWebResponse)task.Result)
                        {
                            // Stopwatch shows wrong results
                            // After multiple request watch.Elapsed time arrives 10 seconds
                            // This is wrong be
                            // The same code running in Console Application works corectly
                            Debug.WriteLine("{0}\t{1}\t{2}", response.StatusCode, response.ContentType, watch.Elapsed);

                            // This lines are only in production WiForms app
                            if (EventWebRequestFinished != null)
                            {
                                // Update WinForm GUI elements (add to listboc)
                            }
                        }
                    },

The same issue I have also using DateTime.Now method.


Solution

  • If it's all code, without any static variables and etc., the cause of the problem may be closure of a variable 'watch'. Expression gets first value of variable and all next times uses only this value. Try to send variable value via 3rd parameter 'state' of the FromAsync method.