0

我有一个Animal在一些模拟程序中使用的基类。在这种情况下,一次运行可能长达 500Animal秒。每次运行都设置为让Animal每个“时间步”都做一些事情。所以我只是遍历动物列表,调用DoTimeStep每一个,直到完成所有时间步骤。

每个Animal类都有自己的记录器类,用于为模拟中的每个“时间步”写出数据。这样每个Animal人都有自己的日志文件。它一直运行良好(3 年),直到我们尝试在虚拟机上运行它。然后出于某种原因,记录器引用每隔一段时间就会在“时间步”中为空,然后下一次它将在那里。真正奇怪的部分是StreamWriter记录器内部似乎永远不会忘记其文件的位置。它只是跳过写出该时间步的行。并且错误日志显示NullReferenceExceptionLogger类上。

我找不到这种行为的任何模式。该类Animal没有被销毁和重新创建。记录器在Animal构造函数中创建并在IDispose. 关于如何开始调试此问题的任何想法?

编辑:我只能重新创建 3 只动物,所以 500 个打开的文件不应该是它。但是感谢您的尝试。

编辑:当我发现 Null Exception 的错误时,我不确定我应该做什么。我已经抓住了它,但我不知道如何找出它发生的原因。抱歉显得迟钝。顺便说一句,我确实尝试了 Thread.Sleep(300) 10000 次循环,看看是否有某种我不知道的比赛正在进行。它在循环中从未变为非空。但是 3 秒后,当我骑车穿过其他两只动物并回来时,它不再为空。

4

5 回答 5

5

我会做以下事情。

  1. 设置 VS 在调试器下运行你的程序
  2. 为空引用异常启用第一次机会异常
  3. 调试器 -> 异常 -> 展开公共语言运行时 -> 检查 System.NullReferenceException
  4. 启动程序
  5. 等待

如果复制需要很长时间,我会启动它并回家过夜。它会在早上等你;)

于 2009-02-24T18:29:56.970 回答
2

听起来像一个竞争条件......你是否正确锁定线程之间共享的数据?

编辑:如果这不是竞争条件,我的第二个猜测是虚拟机可能不喜欢同时打开 500 个文件......你调查过吗?

于 2009-02-24T18:28:02.653 回答
0

您是否有可能遇到可能与延迟初始化有关的多线程问题?

于 2009-02-24T18:26:19.397 回答
0

听起来像一个比赛条件。我想出的解决此类问题的最简单的修补程序是:

查找分配空变量的位置。无论它从哪里获取数据,偶尔都会提供空值,对吧?

所以检查那里,如果它返回 null,睡眠 300 毫秒然后再试一次,直到它不为 null。

如果失败超过 10 秒,则以错误退出。不要让它继续处于无效状态。

于 2009-02-24T18:33:36.523 回答
0

这可能与VM有关...我已经看到VMWare与本机c ++应用程序类似的内存问题,其中内存无缘无故地被弄乱了,并且IT表示他们没有对VM做任何事情... (我们都知道这意味着他们正在对 VM 做一些事情)

当虚拟机在未关闭电源的情况下主动从一台服务器移动到另一台服务器时,我看到了奇怪的行为(它基本上重复了几个字节的代码两次,这会导致各种有趣的错误,尤其是在首先关闭资源的情况下)。

但无论如何,如果它只能在虚拟机上重现,我会尝试使用专用资源(不共享或分数处理器或任何东西)将它隔离在开发虚拟机服务器上,看看你是否可以重现它。然后从那里开始......重新添加相同类型的环境,直到你可以重现它。

于 2009-02-25T04:10:28.417 回答