我在我的WCF服务上有以下代码,它抛出System.IndexOutOfRangeException
Dictionary<string, List<ChunkData>> chunkDataTable = cacheManager[cacheKey] as Dictionary<string, List<ChunkData>>;
if (!chunkDataTable.Keys.Contains(ticker))
{
chunkDataTable.Add(ticker, new List<ChunkData>());
}
List<ChunkData> listOfChunks = new List<ChunkData>();
ChunkData lastIncompeleteChunk = null;
if (chunkDataTable[ticker].Count > 0)
{
Logger.Write("Log one"); //I see this logs
if (reqEndDate <= chunkDataTable[ticker].Last().EndDate)
{
//meaning we can directly take last chunk (which can be incompelete too) directly as we dont need to add further data into for now
listOfChunks = chunkDataTable[ticker].Where
(chunk =>
((chunk.StartDate >= reqStartDate && chunk.EndDate <= reqEndDate) || //whole chunks: which lies in between of requested start and end date
(chunk.StartDate <= reqStartDate && reqStartDate <= chunk.EndDate) || //Left Most Chunk: if req start date lies within some chunk (between start and end date of chunk)
(chunk.StartDate <= reqEndDate && reqEndDate <= chunk.EndDate) //Right Most Chunk: if req end date lies within some chunk (between start and end date of chunk)
)).OrderBy(x => x.EndDate).ToList();
}
else
{
listOfChunks = chunkDataTable[ticker].Where
(chunk => !chunk.IsIncomplete &&
((chunk.StartDate >= reqStartDate && chunk.EndDate <= reqEndDate) || //whole chunks: which lies in between of requested start and end date
(chunk.StartDate <= reqStartDate && reqStartDate <= chunk.EndDate) || //Left Most Chunk: if req start date lies within some chunk (between start and end date of chunk)
(chunk.StartDate <= reqEndDate && reqEndDate <= chunk.EndDate) //Right Most Chunk: if req end date lies within some chunk (between start and end date of chunk)
)).OrderBy(x => x.EndDate).ToList();
if (chunkDataTable[ticker].Last().IsIncomplete)
lastIncompeleteChunk = chunkDataTable[ticker].Last();
}
if (listOfChunks != null)
Logger.Write("Line two"); //I don't see this log
}
reqEndDate
和reqStartDate
来自客户端计算机,按照日志,它们是正确的。 cacheManager
是Microsoft企业库的缓存管理器
完整堆栈跟踪:
System.IndexOutOfRangeException: Index was outside the bounds of the array.
at System.Collections.Generic.List`1.get_Item(Int32 index)
at System.Linq.Enumerable.Last[TSource](IEnumerable`1 source)
我想知道,在什么时候可能发生这种异常
堆栈跟踪表明这是一个威胁问题。 Last()
实现如下:
IList<TSource> sourceList = source as IList<TSource>;
if (sourceList != null)
{
int count = sourceList.Count;
if (count > 0)
return sourceList[count - 1];
}
因此,如果IEnumerable
传递实现IList
(就像你的情况一样),它将首先在一个变量中保存总长度,然后将访问最后一个元素。如果source
中的元素数量在sourceList.Count
和sourceList[count - 1]
语句之间发生了变化,那么抛出堆栈跟踪异常的唯一方法是,这只能由另一个线程完成。
如果您使用共享缓存 - 可以由另一个WCF线程进行更改。所以要修复 - 在处理共享缓存中的项目时实现正确的同步。