I have an ashx web page that does some light data process. I am timing the process duration and for each call save this duration in an application variable so I can do some stats later on (e.g. average process duration per minute).
var startProcess = DateTime.UtcNow;
/*
Do some process here
*/
var duration = DateTime.UtcNow.Subtract(startProcess).TotalMilliseconds;
// makes sure the application variable is initialized
if (HttpContext.Current.Application["ProcessSpeed"] == null)
HttpContext.Current.Application["ProcessSpeed"] = new List<KeyValuePair<string, double>>();
// Adds speed of current process in application variable
((List<KeyValuePair<string, double>>)HttpContext.Current.Application["ProcessSpeed"]).Add(new KeyValuePair<string, double>(startProcess.ToString("HH:mm"), duration));
// makes sure we don't keep too much data in memory (remove oldest one)
if (((List<KeyValuePair<string, double>>)HttpContext.Current.Application["ProcessSpeed"]).Count > 5000)
((List<KeyValuePair<string, double>>)HttpContext.Current.Application["ProcessSpeed"]).RemoveAt(0);
All this has been working fine for months until recently when I started to get an errors on the line that adds the new duration to the array. Error is:
System.IndexOutOfRangeException: Index was outside the bounds of the array. at System.Collections.Generic.List`1.Add(T item) at S01Service.ProcessRequest(HttpContext context) in c:\inetpub\wwwroot\BigServices\S01.ashx:line 79 at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)
The only way to get this back on track is to recycle the IIS pool as calls to the page fail. Then this can work fine for another few weeks before it fails again.
My questions:
- Why is the index outside the bounds of the array when the variable is declared on the previous row (if null)
- Is what I'm doing "good practice"? Reason for not using the db to log the duration is purely for speed purposes (saving in memory is instant whereas I would waste precious milliseconds calling a database).
Just in case that is relevant, this page is called about 2500 times per minutes