简体   繁体   English

C#:模糊的对象引用错误

[英]C# : Obscure object ref error

Have an app which has been running fine for a while. 有一个运行良好一段时间的应用程序。 All of a sudden it has started throwing intermitent "Object reference not set...." errors at a certain line of code on the product server. 突然,它开始在产品服务器上的特定代码行上引发间歇性“未设置对象引用...。”错误。

I started the app in Visual Studio and debugged it with a breakpoint at the offending line of code and have replicated a really strange behaviour. 我在Visual Studio中启动了该应用程序,并在有问题的代码行中使用断点对其进行了调试,并复制了一个非常奇怪的行为。

Initially when VS breaks at the line of code breakpoint, the variable is NULL but if I wait 5 secs or so then the variable is no longer NULL. 最初,当VS在代码断点处中断时,该变量为NULL,但是如果我等待5秒钟左右,则该变量不再为NULL。 This can be sped up by calling the variable in the Immediate Window in VS which causes the NULL field to populate or resolve instantly. 可以通过在VS中的“立即窗口”中调用变量来加快速度,这将导致NULL字段立即填充或解析。 This is the exact intermitent nature of the error on the production server. 这是生产服务器上错误的确切间歇性质。

Any ideas where to start? 任何想法从哪里开始? The data is loaded into the variable before hitting the method but for some reason there is a lag in referencing the variable in memory. 在命中该方法之前,数据已加载到变量中,但是由于某些原因,在内存中引用变量存在滞后性。 Heaps of available memory on dev and production servers. 开发和生产服务器上的可用内存堆。

Really strange...need help to locate a place to start to resolve it. 真的很奇怪...需要帮助找到一个开始解决问题的地方。

Thanks in advance. 提前致谢。

Info : .NET 3.5, VS 2008 信息:.NET 3.5,VS 2008

Code : 代码:

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;
        }

The following line is the source of the issue : 以下是问题的根源:

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

If Sometimes b is NULL and other times subModelAComp is NULL. 如果有时b为NULL,而其他时候subModelAComp为NULL。 If i breakpoint this line and in the Immediate Window if i execute "b.comp[0].subModelAComp" it is NULL, i then execute "b" and then execute "b.comp[0].subModelAComp" again and it is no longer NULL. 如果我在此行中断点,并且在即时窗口中执行“ b.comp [0] .subModelAComp”,则为NULL,然后执行“ b”,然后再次执行“ b.comp [0] .subModelAComp”,即为不再为NULL。 The call to "b" seems to force the "subModelAComp" to not be NULL. 对“ b”的调用似乎迫使“ subModelAComp”不为NULL。 There is no code in the getters which could cause this change. 吸气剂中没有代码可能导致此更改。

*** The application is not threaded. ***应用程序未线程化。 No multi-threading implemented **** 没有实现多线程****

Without seeing any code, it's pretty hard to say, but two possibilities: 没有看到任何代码,很难说,但是有两种可能性:

  • Is this definitely a variable, or might it be a property? 这是绝对变量,还是属性? If it's a property, evaluating it once may give a non-null value, but the second evaluation could be null 如果是属性,则对其进行一次评估可能会得出非null值,但第二次评估可能为null

  • Are there multiple threads involved? 是否涉及多个线程? If so, there are two potential problems: 如果是这样,则存在两个潜在问题:

    • If the data is being set in one thread but read in another, the "setting" thread may have written it, but without the "reading" thread reading it, due to caching etc. There are various ways around this - the simplest being to always acquire a lock before accessing shared data. 如果数据是在一个线程中设置的,而在另一个线程中读取的,则由于缓存等原因,“设置”线程可能已经写入了该数据,但没有“读取”线程读取了该数据。有多种解决方法-最简单的方法是访问共享数据之前,请务必获取一个锁。 (Using the same lock for every access to the same piece of data.) (每次访问相同数据都使用相同的锁。)
    • Another thread could be setting the value to null - so you'd see it be non-null, and then later null 另一个线程可能将该值设置为null-因此您会看到它为非null,然后又为null

Any code you could show us would help. 您可以向我们显示的任何代码都会有所帮助。

Hm, my first guesses would be: 嗯,我的第一个猜测是:

  • Is your application multi-threaded? 您的应用程序是多线程的吗? Could another thread be accessing the variable? 另一个线程可以访问该变量吗? During debugging, check the “Threads” debug window and try freezing all the threads except the current one, then see if the variable contents still change unexpectedly. 在调试过程中,检查“线程”调试窗口,并尝试冻结除当前线程以外的所有线程,然后查看变量内容是否仍然意外更改。

  • Is it really a variable? 它真的是变量吗? Or could it be a property getter that has crazy side-effects? 还是它会产生疯狂的副作用? The debugger would trigger those side-effects too when you query the property from the “Watch” window or the “Immediate” window. 当您从“监视”窗口或“立即”窗口查询属性时,调试器也会触发这些副作用。

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

Any ideas where to start? 任何想法从哪里开始? The data is loaded into the variable before hitting the method but for some reason there is a lag in referencing the variable in memory. 在命中该方法之前,数据已加载到变量中,但是由于某些原因,在内存中引用变量存在滞后性。

To me, that assertion smells. 对我来说,这种主张很香。

Are you sure that the data is loaded into the variable before hitting the method? 在确定方法之前,您确定已将数据加载到变量中吗? Perhaps you haven't written any multithreading code, but you may be using some .NET class with asynchronous behavior (events, etc.) I would take this assumption out and debug from there. 也许您还没有编写任何多线程代码,但是您可能正在使用一些具有异步行为(事件等)的.NET类,因此我会排除这种假设并从那里进行调试。 (Meaning, I'd start by setting a breakpoint before the .ForEach calls, or even before CreateModel is called and check each "b" in the list manually) (意味着,我首先要在.ForEach调用之前甚至在调用CreateModel之前设置一个断点,然后手动检查列表中的每个“ b”)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM