Jef*_*man 3 c# weak-references
运行我的多线程应用程序时,我收到 NullReferenceException,但仅当我在调试器之外以 Release 模式运行时。堆栈跟踪被记录下来,它总是指向同一个函数调用。我在函数中放置了几个日志语句来尝试确定它会到达多远,并且每个语句都会被记录,包括函数最后一行的一个。有趣的是,当 NullReferenceException 发生时,函数调用后的语句不会被记录:
// ...
logger.Log( "one" ); // logged
Update( false );
logger.Log( "eleven" ); // not logged when exception occurs
}
private void Update( bool condition )
{
logger.Log( "one" ); // logged
// ...
logger.Log( "ten" ); // logged, even when exception occurs
}
Run Code Online (Sandbox Code Playgroud)
每次调用函数时都不会发生异常。是否有可能在函数执行之前或期间堆栈被破坏,从而导致返回地址丢失,从而导致空引用?我不认为在 .NET 下这种事情是可能的,但我想更奇怪的事情发生了。
我尝试用函数的内容替换对函数的调用,所以一切都内联发生,然后异常发生在如下所示的行上:
foreach ( ClassItem item in classItemCollection )
Run Code Online (Sandbox Code Playgroud)
我已经通过日志验证“classItemCollection”不为空,并且我还尝试将 foreach 更改为 for 以防 IEnumerator 正在做一些有趣的事情,但异常发生在同一行上。
关于如何进一步调查的任何想法?
更新:一些响应者提出了与确保记录器不为空有关的可能解决方案。需要明确的是,在异常开始发生后,出于调试目的添加了日志记录语句。
我找到了我的空引用。就像 Fredrik 和 micahtan 所建议的那样,我没有为社区提供足够的信息来找到解决方案,所以我想我应该发布我的发现来解决这个问题。
这是正在发生的事情的代表:
ISomething something = null;
//...
// the Add method returns a strong reference to an ISomething
// that it creates. m_object holds a weak reference, so when
// "this" no longer has a strong reference, the ISomething can
// be garbage collected.
something = m_object.Add( index );
// the Update method looks at the ISomethings held by m_object.
// it obtains strong references to any that have been added,
// and puts them in m_collection;
Update( false );
// m_collection should hold the strong reference created by
// the Update method.
// the null reference exception occurred here
something = m_collection[ index ];
return something;
Run Code Online (Sandbox Code Playgroud)
问题原来是我使用“某物”变量作为临时强引用,直到 Update 方法获得永久引用。编译器在发布模式下优化掉“something = m_object.Add();” 分配,因为在再次分配之前不会使用“某物”。这允许 ISomething 被垃圾收集,因此当我尝试访问它时它不再存在于 m_collection 中。
我所要做的就是确保在调用 Update 之前保持强引用。
我怀疑这对任何人都有用,但如果有人好奇,我不想让这个问题悬而未决。
| 归档时间: |
|
| 查看次数: |
1569 次 |
| 最近记录: |