C#:模糊对象引用错误

时间:2010-08-14 09:39:26

标签: c# .net-3.5

让应用程序运行良好一段时间。突然间,它开始在产品服务器上的某一行代码中抛出间歇性的“对象引用未设置....”错误。

我在Visual Studio中启动了应用程序,并在违规行代码处使用断点对其进行了调试,并复制了一个非常奇怪的行为。

最初当VS在代码断点处断开时,该变量为NULL但如果我等待5秒左右,则该变量不再为NULL。这可以通过在VS中的立即窗口中调用变量来加速,这会导致NULL字段立即填充或解析。这是生产服务器上错误的确切间隔性质。

任何想法从哪里开始?在访问方法之前将数据加载到变量中,但由于某种原因,在引用内存中的变量时存在滞后。开发和生产服务器上的可用内存大量。

真奇怪......需要帮助才能找到一个地方开始解决它。

提前致谢。

信息:.NET 3.5,VS 2008

代码:

public static List<Model> CreateModel(List<subModelA> subModelAs, List<subModelB> subModelBs, int duration, bool isGroup) {
            List<Model> result = new List<Model>();

            try {
                if (subModelAs != null && subModelAs.Count > 0) {
                    if (subModelBs != null && subModelBs.Count > 0) {

                        subModelBs.ForEach(b => {
                            subModelA a = subModelAs.Find(x => x.id == b.comp[0].subModelAComp.subModel.id);
                            result.Add(CreateNewModel(a, b, duration));
                        });
                    }
                }
            }
            catch (Exception ex) {
                throw ex;
            }
            return result;
        }

以下行是问题的根源:

subModelA a = subModelAs.Find(x => x.id == b.comp[0].subModelAComp.subModel.id);

如果有时b为NULL,则其他时间为subModelAComp为NULL。如果我断开这一行并在立即窗口中,如果我执行“b.comp [0] .subModelAComp”它是NULL,我然后执行“b”然后再次执行“b.comp [0] .subModelAComp”它是不再是NULL。对“b”的调用似乎强制“subModelAComp”不为NULL。 getter中没有可能导致此更改的代码。

***应用程序没有线程化。没有实现多线程****

4 个答案:

答案 0 :(得分:4)

没有看到任何代码,很难说,但有两种可能性:

  • 这绝对是一个变量,还是属于财产?如果它是属性,则对其进行一次评估可能会给出非空值,但第二次评估可能为null

  • 是否涉及多个主题?如果是这样,有两个潜在的问题:

    • 如果数据是在一个线程中设置但在另一个线程中读取,则“设置”线程可能已写入,但由于缓存等没有“读取”线程读取它。有各种方法可以解决这个问题 - 最简单的方法是在访问共享数据之前始终获取锁。 (对每次访问同一条数据使用相同的锁。)
    • 另一个线程可能是将值设置为null - 所以你会看到它是非null,然后是null

您可以向我们展示的任何代码都会有所帮助。

答案 1 :(得分:1)

嗯,我的第一个猜测是:

  • 您的应用程序是多线程的吗?另一个线程可以访问该变量吗?在调试期间,检查“线程”调试窗口并尝试冻结除当前线程之外的所有线程,然后查看变量内容是否仍然意外更改。

  • 它真的是变量吗?或者它是一个具有疯狂副作用的财产获取者?当您从“监视”窗口或“立即”窗口查询属性时,调试器也会触发这些副作用。

答案 2 :(得分:1)

如果它是属性,则在属性设置器上放置一个断点,以便您可以查看堆栈跟踪以查看将其设置为null的内容。

答案 3 :(得分:0)

  

任何想法从哪里开始?数据是   之前加载到变量中   击中方法,但由于某种原因   参考文献有一个滞后   记忆中的变量。

对我而言,这种说法气味。

在点击方法之前,您确定数据已加载到变量中吗?也许您还没有编写任何多线程代码,但是您可能正在使用一些具有异步行为的.NET类(事件等)。我会从这里考虑这个假设并进行调试。 (意思是,我首先在.ForEach调用之前设置断点,或者甚至在调用CreateModel之前设置断点并手动检查列表中的每个“b”)