We have the following code,
ImageButton btn = buttonLookupTable[buttonName] as ImageButton;
if (btn != null)
{
btn.ImageUrl = sUrl;
}
It is almost always works fine, but sometimes we've got the error:
System.ArgumentException: An entry with the same key already exists.
Stack Trace : at System.Collections.Specialized.ListDictionary.Add(Object key, Object value)
at System.Collections.Specialized.HybridDictionary.Add(Object key, Object value)
at System.Web.UI.StateBag.Add(String key, Object value)
at System.Web.UI.WebControls.Image.set_ImageUrl(String value)
I was puzzled, why assigning the value calls Add method. However despite the ADD name, it is documented that if the item already exists in the StateBag object, this method updates the value of the item.
And Reflector shows valid code in System.Web.UI.StateBag.Add:
StateItem item = this.bag[key] as StateItem;
if (item == null)
{
if ((value != null) || this.marked)
{
item = new StateItem(value);
this.bag.Add(key, item);
}
}
I've noticed a few similar errors in event logs:
System.ArgumentException:An entry with the same key already exists.
Stack Trace : at System.Collections.Specialized.ListDictionary.Add(Object key, Object value)
at System.Collections.Specialized.HybridDictionary.Add(Object key, Object value)
at System.Web.UI.StateBag.Add(String key, Object value)
at System.Web.UI.AttributeCollection.Add(String key, String value)
It was noticed, that usually the error happened for the first user openning the site after ASP application pool recycle.
It could be caused by multi-threaded access to the same function during ASP.NET precompilation.
The similar problem was reported here.
UPDATE: I beleive that problem is related to the user control's EnableViewState=false, which we set in Page_Load, and then call btn.ImageUrl=value .
|
My workaround is to add extra try/catch:
catch (ArgumentException exc)
{
string sKnownErrorToIgnore="An entry with the same key already exists";
if(!exc.Message.Contains(sKnownErrorToIgnore))
{
throw;
}
else
{
//ignore in production
Debug.Assert(false, "just debug when it happens" +exc.ToString());
}
}