使用(DNN)的CMS中的一段代码会引发以下异常:
"索引超出了数组的范围。"
堆栈跟踪说:
at System.Collections.Generic.List`1.Contains(T item)
这个问题有时只会发生(我怀疑它与缓存破坏有关)并且只在生产中发生。这意味着我无法一致地重现它。我最感兴趣的是它会如何发生。
对“'包含'”的调用怎么可能?触发索引超出范围?
额外信息
调用Contains的代码按以下方式工作(我已经简化了代码以使重要部分更具可读性。链接导致确切的类和亚麻布)
List<int> urlPortals;
var cc = new CacheController();
cc.GetFriendlyUrlIndexFromCache(out urlPortals);
var boolean = urlPortals.Contains(portalId); // This is where the exception happens.
void GetFriendlyUrlIndexFromCache(out List<int> urlPortals)
{
urlPortals = null;
object rawPortals = DataCache.GetCache(UrlPortalsKey);
if (rawPortals != null)
{
urlPortals = (List<int>)rawPortals;
}
}
object GetCache(string CacheKey)
{
return Cache[cacheKey];
}
完整堆栈跟踪
InnerMessage:Index was outside the bounds of the array.
InnerStackTrace:
at System.Collections.Generic.List`1.Contains(T item)
at DotNetNuke.Entities.Urls.CustomUrlDictController.FetchCustomUrlDictionary(Int32 portalId, Boolean forceRebuild, Boolean bypassCache, FriendlyUrlSettings settings, SharedDictionary`2& customAliasForTabs, Guid parentTraceId)
at DotNetNuke.Entities.Urls.TabPathHelper.GetTabPath(TabInfo tab, FriendlyUrlSettings settings, FriendlyUrlOptions options, Boolean ignoreCustomRedirects, Boolean homePageSiteRoot, Boolean isHomeTab, String cultureCode, Boolean isDefaultCultureCode, Boolean hasPath, Boolean& dropLangParms, String& customHttpAlias, Boolean& isCustomPath, Guid parentTraceId)
at DotNetNuke.Entities.Urls.AdvancedFriendlyUrlProvider.ImproveFriendlyUrlWithMessages(TabInfo tab, String friendlyPath, String pageName, PortalSettings portalSettings, Boolean ignoreCustomRedirects, FriendlyUrlSettings settings, List`1& messages, Boolean cultureSpecificAlias, Guid parentTraceId)
at DotNetNuke.Entities.Urls.AdvancedFriendlyUrlProvider.ImproveFriendlyUrl(TabInfo tab, String friendlyPath, String pageName, PortalSettings portalSettings, Boolean ignoreCustomRedirects, Boolean cultureSpecificAlias, FriendlyUrlSettings settings, Guid parentTraceId)
at DotNetNuke.Entities.Urls.AdvancedFriendlyUrlProvider.FriendlyUrlInternal(TabInfo tab, String path, String pageName, String portalAlias, PortalSettings portalSettings)
at DotNetNuke.Entities.Urls.AdvancedFriendlyUrlProvider.FriendlyUrl(TabInfo tab, String path, String pageName, PortalSettings portalSettings)
at DotNetNuke.Services.Url.FriendlyUrl.DNNFriendlyUrlProvider.FriendlyUrl(TabInfo tab, String path, String pageName, PortalSettings settings)
at DotNetNuke.Common.Globals.NavigateURL(Int32 tabID, Boolean isSuperTab, PortalSettings settings, String controlKey, String language, String pageName, String[] additionalParameters)
at DotNetNuke.Common.Globals.NavigateURL(Int32 tabID, String controlKey, String[] additionalParameters)
at Ventrian.SimpleGallery.RandomPhoto.GetAlbumUrl(String albumID)
at Ventrian.SimpleGallery.RandomPhoto.BindPhoto(PlaceHolder phPhoto, PhotoInfo objPhoto)
at Ventrian.SimpleGallery.RandomPhoto.dlGallery_OnItemDataBound(Object sender, DataListItemEventArgs e)
at System.Web.UI.WebControls.DataList.OnItemDataBound(DataListItemEventArgs e)
at System.Web.UI.WebControls.DataList.CreateItem(Int32 itemIndex, ListItemType itemType, Boolean dataBind, Object dataItem)
at System.Web.UI.WebControls.DataList.CreateControlHierarchy(Boolean useDataSource)
at System.Web.UI.WebControls.BaseDataList.OnDataBinding(EventArgs e)
at System.Web.UI.WebControls.BaseDataList.DataBind()
at Ventrian.SimpleGallery.RandomPhoto.Page_Load(Object sender, EventArgs e)
答案 0 :(得分:4)
因为你只想知道Contains如何导致越界异常,所以这是如何。
这是Contains的实现方式:
来自http://referencesource.microsoft.com/#mscorlib/system/collections/generic/list.cs,cf7f4095e4de7646
的来源public bool Contains(T item) {
if ((Object) item == null) {
for(int i=0; i<_size; i++)
if ((Object) _items[i] == null)
return true;
return false;
}
else {
EqualityComparer<T> c = EqualityComparer<T>.Default;
for(int i=0; i<_size; i++) {
if (c.Equals(_items[i], item)) return true;
}
return false;
}
}
当大小不正确(竞争条件?)时,内部数组访问将抛出异常
答案 1 :(得分:3)
我在DNN中打开了一个解决此问题的拉取请求。我们遇到了这个问题,在进行更改后,我们在错误日志中没有看到此堆栈跟踪。