views:

26

answers:

1

Here's the error

System.IndexOutOfRangeException.  
Index was outside the bounds of the array.  
at System.Collections.ArrayList.get_Item(Int32 index)  
at System.Collections.Specialized.NameObjectCollectionBase.NameObjectKeysEnumerator.get_Current()  
at System.Web.TraceContext.EndRequest()  
at System.Web.UI.Page.ProcessRequestEndTrace()  
at System.Web.UI.Page.ProcessRequest(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)  
at System.Web.UI.Page.ProcessRequest()  
at System.Web.UI.Page.ProcessRequest(HttpContext context)  
at ASP.meebo_html.ProcessRequest(HttpContext context)  
at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()  
at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)

We do have a custom trace listener. Here's the code.

using System;
using System.Diagnostics;
using System.Collections.Generic;

namespace Zinch.Debug
{
public class ZinchTraceListener : TraceListener
{
    public ZinchTraceListener()
    {

    }

    public static ZinchTraceEventCollection GetTraceList()
    {
        if (System.Web.HttpContext.Current == null)
            return new ZinchTraceEventCollection();

        ZinchTraceEventCollection list = (ZinchTraceEventCollection)System.Web.HttpContext.Current.Items["TraceCollection"];
        if (list == null)
        {
            list = new ZinchTraceEventCollection();
            System.Web.HttpContext.Current.Items.Add("TraceCollection", list);
        }
        return list;
    }

    public override void Write(string message)
    {
        ZinchTraceEventCollection trace = GetTraceList();
        trace.Add(message);
    }

    public override void WriteLine(string message)
    {
        Write(message);
    }
}

public class ZinchTraceEvent
{
    public ZinchTraceEvent()
    {
    }

    public ZinchTraceEvent(string message)
    {
        _message = message;
        _timestamp = DateTime.Now;
    }

    private DateTime _timestamp;
    public DateTime TimeStamp
    {
        get { return _timestamp; }
        set { _timestamp = value; }
    }

    private string _message;
    public string Message
    {
        get { return _message; }
        set { _message = value; }
    }

    private double _sincelast;
    public double SinceLast
    {
        get { return _sincelast; }
        set { _sincelast = value; }
    }

    private double _sincefirst;
    public double SinceFirst
    {
        get { return _sincefirst; }
        set { _sincefirst = value; }
    }
}

public class ZinchTraceEventCollection : List<ZinchTraceEvent> 
{
    private object lockObject = new object();
    public void Add(string message)
    {
        ZinchTraceEvent item = new ZinchTraceEvent(message);
        if (this.Count > 0)
        {
            ZinchTraceEvent first = this[0];
            ZinchTraceEvent last = this[this.Count - 1];

            item.SinceFirst = (item.TimeStamp - first.TimeStamp).TotalMilliseconds;
            item.SinceLast = (item.TimeStamp - last.TimeStamp).TotalMilliseconds;
        }
        lock (lockObject)
        {
            Add(item);
        }
    }

    public override string ToString()
    {
        System.Xml.Serialization.XmlSerializer serializer = new System.Xml.Serialization.XmlSerializer(typeof(ZinchTraceEventCollection));
        using (System.IO.StringWriter writer = new System.IO.StringWriter())
        {
            lock (lockObject)
            {
                serializer.Serialize(writer, this);
            }
            return writer.ToString();
        }
    }
}

}

I can't think of anything else that might be causing the error, but I also don't see how this class would be causing it either. Any suggestions on where to look? I've never been able to reproduce it in a Dev environment, but it happens frequently enough in production that it can't be ignored either.

+1  A: 

Should the index should be >1 (you have > 0)?

 if (this.Count > 1){

    ZinchTraceEvent first = this[0];
    ZinchTraceEvent last = this[this.Count - 1];
}

There is a chance it is a race condition.. but i bet its the above.

 ZinchTraceEventCollection list =     
    (ZinchTraceEventCollection)System.Web.HttpContext.Current.Items["TraceCollection"];
 if (list == null)
Nix
#1 seems reasonable. I do understand race conditions. Can you tell me more about what you are thinking in this case?
Al W
if for some reason two people hit the block of the second code above, you would have two different instances of list.Did the check on count > 1 not fix it?
Nix