We were using a previous version of mvp and got the error:
[IndexOutOfRangeException: Index was outside the bounds of the array.]
System.Collections.Generic.Dictionary`2.Insert(TKey key, TValue value, Boolean add) +7460198
System.Collections.Generic.Dictionary`2.set_Item(TKey key, TValue value) +11
Mvp.Xml.Common.XPath.XPathCache.GetCompiledExpression(String expression, XPathNavigator source) +68
Mvp.Xml.Common.XPath.XPathCache.SelectNodes(String expression, XmlNode source) +25
I saw this has been changed already: now a Hashtable is being used as cache. But still, this is not completely fixed, because the Hashtable is also not thread-safe, so you should use locking. Otherwise it might throw errors if you are adding more than one element at the same time to the cache.
My suggestion for the code would be:
private static readonly Dictionary<string, XPathExpression> Cache = new Dictionary<string, XPathExpression>();
/// <summary>
/// Retrieves a cached compiled expression, or a newly compiled one.
/// </summary>
private static XPathExpression GetCompiledExpression(string expression, XPathNavigator source)
{
if (!Cache.ContainsKey(expression))
{
XPathExpression expr = source.Compile(expression);
lock (Cache)
if (!Cache.ContainsKey(expression)) // it might have been added in the meanwhile
Cache.Add(expression, expr);
}
return Cache[expression].Clone();
}
[IndexOutOfRangeException: Index was outside the bounds of the array.]
System.Collections.Generic.Dictionary`2.Insert(TKey key, TValue value, Boolean add) +7460198
System.Collections.Generic.Dictionary`2.set_Item(TKey key, TValue value) +11
Mvp.Xml.Common.XPath.XPathCache.GetCompiledExpression(String expression, XPathNavigator source) +68
Mvp.Xml.Common.XPath.XPathCache.SelectNodes(String expression, XmlNode source) +25
I saw this has been changed already: now a Hashtable is being used as cache. But still, this is not completely fixed, because the Hashtable is also not thread-safe, so you should use locking. Otherwise it might throw errors if you are adding more than one element at the same time to the cache.
My suggestion for the code would be:
private static readonly Dictionary<string, XPathExpression> Cache = new Dictionary<string, XPathExpression>();
/// <summary>
/// Retrieves a cached compiled expression, or a newly compiled one.
/// </summary>
private static XPathExpression GetCompiledExpression(string expression, XPathNavigator source)
{
if (!Cache.ContainsKey(expression))
{
XPathExpression expr = source.Compile(expression);
lock (Cache)
if (!Cache.ContainsKey(expression)) // it might have been added in the meanwhile
Cache.Add(expression, expr);
}
return Cache[expression].Clone();
}