2009-02-24 3 views
0

У меня есть базовый класс Animal, который я использую в некоторых программах моделирования. В этом случае может быть до 500 Animal с. Каждый запуск настроен таким образом, чтобы каждый Animal выполнял что-то каждый «шаг времени». Поэтому я просто просматриваю список животных, звоните DoTimeStep на каждом из них, пока все действия не выполняются для запуска.Как отлаживать несовместимую нулевую ссылку в C#?

Каждый класс Animal имеет свой собственный класс регистратора для записи данных для каждого «шага времени» в симуляции. Таким образом, каждый Animal имеет свой собственный файл журнала. Он работал отлично навсегда (3 года), пока мы не попытались запустить его на виртуальной машине. Затем, по какой-либо причине, каждый раз, когда ссылка на журнал хранится в нулевом значении для «временного шага», а затем в следующий раз она будет там. На самом деле странная часть: StreamWriter внутри регистратора, похоже, не теряет следа, где находится его файл. Он просто пропускает запись строки для этого временного шага. И журнал ошибок показывает NullReferenceException в классе Logger.

Я не могу найти шаблонов для этой ситуации. Класс Animal не был уничтожен и воссоздан. Регистратор создается в конструкторе Animal и уничтожается в IDispose. Любые идеи о том, как я начну отлаживать эту проблему?

Редактировать: я могу воссоздать это будет только 3 животных, поэтому 500 открытых файлов не должно быть. Но спасибо за попытку.

Редактировать: Я не уверен, что я должен делать, когда я уловил ошибку для Null Exception. Я уже поймал это, но я не могу понять, как узнать, почему это происходит. Извините за кажущуюся тупой. В стороне я попробовал Thread.Sleep (300) для 10000 циклов, чтобы узнать, не происходит ли какая-то гонка, о которой я не знал. В цикле он никогда не становился нулевым. Но через 3 секунды, когда я перебрался через двух других животных и вернулся, он больше не был нулевым.

+0

Какую виртуальную машину вы используете? Можем ли мы увидеть код журнала, о котором идет речь, что вызывает исключение? –

ответ

0

Есть ли вероятность, что вы столкнулись с проблемами многопоточности, возможно, связанные с ленивой инициализацией?

2

Звучит как условие гонки ... Вы правильно фиксируете данные, разделяемые между нитями?

EDIT: Если это не состояние гонки, мои секундные предположения состоят в том, что, возможно, виртуальная машина не любит открывать одновременно 500 файлов ... Вы изучили это?

+0

Интересная точка с VM, не позволяющая открывать 500 файлов. –

5

Я бы сделал следующее.

  1. установки VS, чтобы запустить программу под отладчиком
  2. Включить первый шанс исключение для нулевой ссылки Исключения
  3. Debugger -> Исключения -> Expand Common Language Runtime -> Проверить брошенную для System.NullReferenceException
  4. Запустите программу
  5. Wait

Если это занимает много времени, чтобы Репрографическим я хотел бы начать это и пойти домой Ф.О. ночь. Он будет ждать вас утром;)

0

Звучит как гонка состояние. Самое легкое исправление патча, которое я придумал для решения этой проблемы:

Найти, где назначается нулевая переменная. Как бы то ни было, это данные изредка подают нуль, не так ли?

Итак, проверьте там, если он вернет нулевое значение, засыпайте за 300 мс, а затем повторите попытку, пока он не будет равен нулю.

Если он не работает более, чем, скажем, 10 секунд, выдается с ошибкой. Не допускайте его продолжения в недействительном состоянии.

0

Это может быть что-то связанное с VM ... Я видел похожие проблемы с памятью с VMWare с родными приложениями на C++, где без всякой причины память перепуталась, и ИТ говорит, что они ничего не делали с VMs ... (и все мы знаем, что это означает, что они что-то делали с VM)

Я видел странное поведение, когда виртуальная машина активно перемещается с одного сервера на другой, а не отключается (в основном это повторяет несколько байтов кода, что вызывает всевозможные интересные ошибки, особенно если сначала были закрыты ресурсы).

Но в любом случае, если он только воспроизводится на виртуальной машине, я попытался бы изолировать его на сервере dev VM самостоятельно с использованием выделенных ресурсов (без использования разделяющих или дробных процессоров или чего-то еще) и посмотреть, можете ли вы воспроизвести его. Затем перейдите оттуда ... для повторного добавления обратно того же типа среды, пока вы не сможете воспроизвести его.