Linq.Enumerable的界外索引 [英] Index Out of Bounds in Linq.Enumerable

查看:29
本文介绍了Linq.Enumerable的界外索引的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在我正在使用的服务中间歇性地收到此错误

I've been getting this error intermittently in a service I'm working on

消息:System.IndexOutOfRangeException:索引超出数组的范围.在System.Collections.Generic.List 1.Enumerator.MoveNext()在System.Linq.Enumerable中.< ExceptIterator> d__99 1.MoveNext()在System.Linq.Enumerable.ElementAtOrDefault [TSource](IEnumerable`1源,Int32索引)

Message: System.IndexOutOfRangeException: Index was outside the bounds of the array. at System.Collections.Generic.List1.Enumerator.MoveNext() at System.Linq.Enumerable.<ExceptIterator>d__991.MoveNext() at System.Linq.Enumerable.ElementAtOrDefault[TSource](IEnumerable`1 source, Int32 index)

代码如下:

List<ApplicationNames> originalApplicationNames = new List<ApplicationNames>(copyOfCachedVersions.Keys.ToList());
var exceptNames = applicationNames.Except( originalApplicationNames );
if (exceptNames != null && exceptNames.ElementAtOrDefault(0) != default(ApplicationNames))

基本上,if语句应该检查exceptionNames是否包含任何元素.我已经尝试过使用exceptionNames.Count()> 0和exceptionNames.Any(),并且得到相同的错误消息.我也尝试过

Basically, the if statement is supposed to check if exceptNames has any elements. I've already tried using exceptNames.Count() > 0 and exceptNames.Any(), and I get the same error message. I've also tried

var exceptNames = applicationNames.Except( originalApplicationNames ).ToList(); 

结果相同

我现在真的很困,所以任何帮助将不胜感激!

I'm really stuck at this point, so any help would be greatly appreciated!

推荐答案

applicationNames 是一个静态对象,因此多个线程可以同时访问它.但是,这里有锁定功能以防止他们同时修改它

applicationNames is a static object, so several threads would have access to it simultaneously. However, there is locking in place to prevent them from modifying it concurrently

当可以同时修改和读取集合时,仅阻止并发修改是不够的.您需要防止与修改同时发生的读取,否则您将看到随机异常.

When a collection can be modified and read at the same time, it is not enough to prevent concurrent modification. You need to prevent reads that happen concurrently with modification, otherwise you would see random exceptions.

您可以通过制作 applicationNames 的副本来解决此问题:

You can work around this by making a copy of applicationNames:

private static IList<ApplicationNames> ApplicationNamesSync {
    get {
        // Use the same synchronization that prevents concurrent modifications
        lock (appNamesLock) {
            return applicationNames.ToList(); // Make a copy
        }
    }
}

现在您的代码可以使用了:

Now your code will work:

List<ApplicationNames> originalApplicationNames = new List<ApplicationNames>(copyOfCachedVersions.Keys.ToList());
var exceptNames = ApplicationNamesSync.Except( originalApplicationNames );
if (exceptNames != null && exceptNames.ElementAtOrDefault(0) != default(ApplicationNames)) {
    ...
}

这篇关于Linq.Enumerable的界外索引的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆