Странное исключение nullreference

Итак, у меня есть этот код, который заботится о подтверждении команд с удаленных компьютеров, иногда (например, один раз в 14 дней или что-то в этом роде) следующая строка выдает исключение нулевой ссылки:

computer.ProcessCommandAcknowledgment( commandType );

Что меня действительно беспокоит, так это то, что я проверяю перед ним нулевую ссылку, поэтому у меня есть нет идея, что происходит. Вот полный метод того, чего он стоит:

    public static void __CommandAck( PacketReader reader, SocketContext context )
    {
        string commandAck = reader.ReadString();

        Type commandType = Type.GetType( commandAck );

        Computer computer = context.Client as Computer;

        if (computer == null)
        {
            Console.WriteLine("Client already disposed. Couldn't complete operation");
        }
        else
        {
            computer.ProcessCommandAcknowledgment( commandType );
        }
    }

Какие-нибудь подсказки?

Обновлено: ProcessCommandAcknowledgment:

    public void ProcessCommandAcknowledgment( Type ackType )
    {
        if ( m_CurrentCommand.GetType() == ackType )
        {
            m_CurrentCommand.Finish();
        }
    }

Можете ли вы указать 1) несколько потоков (да / нет), 2) версию CLR и 3) архитектуру процессора

JaredPar 27.12.2008 04:14

Однопоточный / 2.0.50727.1433 / x86

arul 27.12.2008 04:18

Можете ли вы опубликовать подпись (и) для ProcessCommandAcknwoldgement?

JaredPar 27.12.2008 04:27

Можете ли вы опубликовать трассировку стека исключения?

Mark Brackett 27.12.2008 06:17
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
4
455
8
Перейти к ответу Данный вопрос помечен как решенный

Ответы 8

Возможно ли, что ReadString() возвращает ноль? Это приведет к сбою GetType. Возможно, вы получили пустой пакет? В качестве альтернативы, строка может не соответствовать типу, и поэтому commandType будет иметь значение null при дальнейшем использовании.

РЕДАКТИРОВАТЬ: Вы проверили, что m_CurrentCommand не равен нулю при вызове ProcessCommandAcknowledgment?

Нет, nullref выбрасывается в выделенную мной строку, пакеты на 100% достоверны и полны. (хеш-контроль + они зашифрованы).

arul 27.12.2008 02:28

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

arul 27.12.2008 02:31

Никакая часть кода никогда не устанавливает для него значение null. В ctor по умолчанию используется Command.Invalid.

arul 27.12.2008 08:51

Исходя из предоставленной вами информации, совершенно невозможно, чтобы в этом месте возникла пустая ссылка. Итак, следующий вопрос: «Как узнать, что конкретная строка создает исключение NullReferenceException?» Вы используете отладчик или информацию о трассировке стека? Вы проверяете розничную или отладочную версию кода?

Если это отладчик, различные комбинации настроек, которые могут привести к тому, что отладчик появляться будет сообщать о NullRef в другом месте. Главное, что это может сделать, - это настройка Just My Code.

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

  1. Выключите JMC
  2. Скомпилировать с отладкой
  3. Отладчик -> Настройки -> Прерывание при выдаче исключений CLR.
  4. Проверьте свойство StackTrace в окне отладчика

У меня есть подробная трассировка стека PDB. Информация верна на 100%.

arul 27.12.2008 03:33

Я готов поспорить, что есть проблема с вашим кодом кадрирования TCP (если он у вас есть!)

«PacketReader», возможно, предполагает, что вы этого не сделаете. Потому что технически это называлось бы "FrameReader" или что-то подобное, если бы вы это сделали.

Если два задействованных компьютера находятся в локальной сети или что-то в этом роде, это, вероятно, объяснит 14-дневный интервал. Если бы вы попробовали это через Интернет, я уверен, что ваша частота ошибок будет гораздо более распространенной, особенно если бы была ограничена пропускная способность WAN.

Недействительные пакеты отбрасываются, а отправившие их клиенты отключаются. Сначала проверяется crc полезной нагрузки, затем пакеты распаковываются и, наконец, дешифруются. Если какой-либо из этих шагов не удается, клиент отключается.

arul 27.12.2008 03:38

Если у вас включена оптимизация, скорее всего, вы укажете совсем не то место, где это на самом деле происходит.

Нечто подобное случилось со мной несколько лет назад.

Что ж, он надежно работал с теми же настройками компилятора. Всегда указывал на то место, где была ошибка. Только в этом конкретном случае, похоже, есть проблема.

arul 27.12.2008 03:43

Или же возможная гонка потоков где-то, где контекст получает значение null другим потоком. Это также объясняет необычность ошибки.

Хорошо, на самом деле есть только несколько возможностей.

  1. Каким-то образом ваш компьютерный справочник попадает под удар, когда вы вызываете эту рутину.

  2. Что-то под вызовом вызывает ошибку разыменования нулевого указателя, но обнаруживается в этой строке.

Глядя на это, я очень подозреваю, что стек поврежден, что приводит к автоматическому искажению вашего computer. Проверьте подпрограмму / метод / функцию, вызывающую вокруг, с которой у вас возникли проблемы; в частности, убедитесь, что то, что вы превращаете в предмет «Компьютер», действительно соответствует вашим ожиданиям.

Спасибо, есть подсказки, как его отладить?

arul 27.12.2008 03:43

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

Charlie Martin 27.12.2008 04:24

О, в этом обработчике исключений посмотрите, что действительно дает вам Console.client.

Charlie Martin 27.12.2008 04:25
Ответ принят как подходящий

Что делают другие потоки?

Обновлено: вы упоминаете, что сервер является однопоточным, но другой комментарий предполагает, что эта часть является однопоточным. Если это так, у вас все еще могут быть проблемы с параллелизмом.

Суть здесь, я думаю, в том, что у вас либо проблема с многопоточностью, либо ошибка CLR. Вы можете догадаться, что мне кажется более вероятным.

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

arul 28.12.2008 04:57

@arul - Ваше резервное поле объявлено нестабильным? Вы снимаете блокировки, когда устанавливаете это поле? Могут быть несколько менее очевидные проблемы с параллелизмом.

Mark Brackett 28.12.2008 07:08

Это локальная переменная, которая существует в стеке и не может быть объявлена ​​как изменчивая.

arul 29.12.2008 02:29

Поле поддержки для Context.Client, возможно, должно быть изменчивым.

Mark Brackett 29.12.2008 03:06

Объявление его нестабильным, вероятно, решило проблему, я имею в виду, с тех пор этого не происходило.

arul 21.01.2009 22:27

computer.ProcessCommandAcknowledgment( commandType );

Есть ли у вас отладочные символы, чтобы в это можно было войти?

Исключение нулевой ссылки могло быть вызвано ProcessCommandAcknowledgement и всплыло.

Ага. Кроме того, ProcessCommandAcknowledgement принимает нулевую команду.

arul 27.12.2008 03:50

Другие вопросы по теме