【问题标题】:Argument Exception thrown by Generic.List when using AddRange with an empty Generic.List as argument使用带有空 Generic.List 作为参数的 AddRange 时 Generic.List 引发的参数异常
【发布时间】:2019-11-08 15:36:14
【问题描述】:

在我的程序中,当我尝试使用 AddRange 函数时,我得到一个未处理的 System.ArgumentException

目标数组不够长。检查 destIndex 和长度,以及数组的下限。

在调试时,我打破了我所在行的异常:

ListA.AddRange(ListB);

在调试器的监视工具中,我可以看到:

ListA: Count = 2454
ListB: Count = 0

查看documentation 的通用列表,ArgumentException 未列出。

当我试图查明到底出了什么问题时,我是否遗漏了什么?

【问题讨论】:

  • 您是否同时从多个线程访问列表?
  • 能否请您填写您的ListA的定义?
  • 是的,我愿意。我将在帖子中添加该信息。你能解释一下相关性吗?
  • @Anduin 你的意思是它是什么样的列表?它被初始化为 List,其中 MyObject 是抽象的,并且有许多不同类型的子对象。
  • 是的。这很重要。我需要确定它是List 还是其他集合类型。

标签: c# exception generic-list addrange


【解决方案1】:

List<T> 不是线程安全的。来自the docs

线程安全

这种类型的公共静态(在 Visual Basic 中为共享)成员是线程安全的。不保证任何实例成员都是线程安全的。

对 List 执行多个读取操作是安全的,但如果在读取时修改集合,则可能会出现问题。为确保线程安全,请在读取或写入操作期间锁定集合。要使一个集合能够被多个线程访问以进行读写,您必须实现自己的同步。对于具有内置同步的集合,请参阅 System.Collections.Concurrent 命名空间中的类。有关固有的线程安全替代方案,请参阅 ImmutableList 类。

从多个线程同时写入List<T> 或在一个线程上写入List<T> 而在另一个线程上读取它是安全的。您会看到随机的“无法解释的”异常,就像您看到的那样。

使用锁来正确同步对您的列表的访问、使用线程安全集合或重新架构,这样您就不需要这样做了。

【讨论】:

  • 感谢您对canton7的帮助。非常感谢。
【解决方案2】:

编辑:不要介意我的帖子的其余部分。这是一个比赛条件。这显然发生在最后的 AddRange 部分。显然,在增长步骤和实际副本期间,任一数组的大小都不同。而到了这样的程度,内部阵列还没有足够增长。

simple lock block 涵盖任一阵列上的所有写入工作应该可以解决这个问题。

原始答案 - 可以忽略

你的标题解释了它。您得到一个参数异常,因为您尝试将一个空列表添加到现有列表中。根据 AddRange() 函数的设计者,这不是一个有效的操作。

ArgumentException 的用途非常狭窄:

当提供给方法的参数之一无效时引发的异常。

当调用方法并且至少有一个传递的参数不符合被调用方法的参数规范时,将引发ArgumentException。 ParamName 属性标识无效参数。

因为它有一个目的,所以对于每个函数调用中可能发生的每种情况都不需要特别提及。确实应该鼓励你自己扔。

为避免这种情况,不要将空列表输入 AddRange()。检查以下内容将是微不足道的:

if(ListB.Lent > 0){
  ListA.AddRange(ListB);
}

由于您提供了关于如何创建 ListB 的 0 信息,我们无法告诉您为什么此时它有时为空。就是这样,很容易检查。

我使用这两篇​​文章作为我的异常处理的基础:

这个异常是简单明了的Boneheaded异常。空列表有一个远程参数不是那么特殊。然而,AddRange() 的设计者认为它足以保证例外。使用基本 if 也可以轻松避免,因此不能真正将其归类为 Vexing Exception。因此,即使经过所有考虑,它仍然只是一个 Boneheaded 例外。请停止造成它。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-05-16
  • 2011-03-14
  • 1970-01-01
  • 2018-09-23
  • 1970-01-01
相关资源
最近更新 更多