【问题标题】:foreach throws NullReferenceException on ObservableCollectionforeach 在 ObservableCollection 上抛出 NullReferenceException
【发布时间】:2012-11-21 14:18:02
【问题描述】:

我有class ElementRelation { ... }class ElementRelationCollection : System.Collections.ObjectModel.ObservableCollection<ElementRelation> { ... }

我有这个代码:

ElementRelationCollection a = ...;
if (a == null)
    throw new Exception("a is null(???)"); // this exception is never thrown
try
{
    foreach (ElementRelation relation in a) // exception is thrown here
    { ... } // never thrown here
}
catch (NullReferenceException ex)
{
    string message = "Something is null here. a.Count: " + a.Count;
    IEnumerator<ElementRelation> enumerator = a.GetEnumerator();
    message += ", enumerator is " + (enumerator == null ? "null" : "not null");
    throw new Exception(message, ex);
}

我可以从日志中看到,这段代码有时会抛出带有消息的异常 “这里有些东西是空的。a.Count:9,枚举器不为空”。当这种情况开始发生时,它会在每次页面加载时继续发生,直到我 iisreset。

当然,内部异常是 System.NullReferenceException,它有这个堆栈跟踪:

at MyNamespace.MyClass.MyMethod() in c:\path\MyClass.cs:line 74

第 74 行是foreach (ElementRelation relation in a) 的行

为什么会抛出这个异常?

编辑:

集合有时由后台线程更新。我认为这不会导致比迭代失败更严重的问题,但事实证明整个集合都已损坏。

【问题讨论】:

  • 您确定您的 PDB 根据来源是最新的吗?这是调试版本还是发布版本?
  • 还有 - 这段代码是基于实例的还是静态的?
  • ElementRelationCollection 长什么样子?堆栈跟踪在哪里?
  • 发布版本。调试时从未见过错误。 PDB 文件似乎是最新的。我们删除所有 obj 和 bin 文件,进行完整的重建并将它们同时发布到网络服务器。外部异常的行号与代码中的行号相匹配 throw new Exception(message, ex); MyClass 是可以实例化的,方法不是静态的。
  • 您将不得不在问题中包含更多内容 a) 堆栈跟踪 b) foreach 中发生了什么 c) @987654328 中的代码@如果它以某种非标准方式实现了可枚举模式。

标签: c# .net foreach observablecollection nullreferenceexception


【解决方案1】:

ObservableCollection&lt;T&gt; 类不是线程安全的。从多个线程修改它可能会破坏内部状态,以至于无法修改或枚举实例。

您会随机看到 NullReferenceExceptionIndexOutOfRangeException 等异常 - 这是最好的结果!在其他情况下,可以静默删除对集合的更改。

您要么需要将您对列表的访问权限封装在一个锁中,可能使用the ReaderWriterLockSlim class,要么切换到一个线程安全的集合。对于 .NET 4.0,System.Collections.Concurrent namespace 有多种可能性。

【讨论】:

    猜你喜欢
    • 2020-10-22
    • 1970-01-01
    • 2013-05-30
    • 1970-01-01
    • 2020-11-17
    • 2016-03-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多