2013-05-21 3 views
0

SOLVED: код был удален через события каждые 10 мс, увеличивая время, необходимое для решения проблемы.Оператор C# false if

Я испытываю странный IndexOutOfRangeException, который не должен происходить. Код внутри оператора if используется, хотя сам оператор является «ложным». Это известная проблема? Если да, то как я могу это исправить?

Ошибка возникает, когда счетчик (int) равен 0, таким образом запрашивая element -1 от array Огни.

Код:

if (counter > 0) 
    { 
    Console.WriteLine("counter-1 is groter dan 0"); 
    int i = counter - 1; 
    Lights[i].setState(0); 
    } 
+0

Доступен ли счетчик из любых других потоков? –

+0

Прошу прощения, но это невозможно.Если if-statement является ложным, код внутри оператора не будет выполнен, если у вас нет проблемы с несколькими потоками. Не могли бы вы разместить больше своего кода, чтобы мы могли видеть, что вы делаете? –

+0

Изображение ошибки можно увидеть здесь: http://s13.postimg.org/a0frmariv/indexoutofrange.jpg Я также был очень удивлен, увидев это. Приложение является однопоточным приложением, а счетчик - частной переменной , – Simon

ответ

0

Таймер выстрелил событий каждые 10 мс. Это создало возможность вешать на:

  • Программа получает внутри условного оператора во время события А.
  • Новое событие B увольняют и процессор заботиться о событии В.
  • Событие B изменение счетчика к отрицательному значению, что делает утверждение if-false ложным.
  • ЦП, изменяющееся, чтобы позаботиться о событии A.
  • Теперь программа находится внутри оператора if, даже если сам оператор if является ложным.

Проблема была решена за счет того, что события происходили реже.

+0

Проблема не решена. Это просто похоже, что это произойдет. –

+0

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

1

Если счетчик не доступен/манипулируют в многопоточном образом - это должно быть невозможно состояние.

вы всегда можете попробовать делает задание & проверку в одном месте:

var index = 0; 

if ((index = (counter - 1)) > 0) 
{ 
    Lights[index].setState(0); 
} 
+0

Это просто делает код сложнее читать и сложнее отлаживать imho. Он не делает ничего для безопасности потока. – Steve

0

Если нет других потоков изменения counter в фоновом режиме, то единственным возможным объяснением является то, что Lights[] коллекция имеет нулевой размер.

Перед доступом к его элементам попробуйте проверить длину Lights.

+0

, но это объясняет, что код выполняется, несмотря на то, что условие, оценивающее значение false – tariq

+0

@tariq Я не верю, что это то, что происходит. Я думаю, что на самом деле происходит то, что 'Lights []' имеет нулевой размер. Но я согласен, что сообщение в связанном изображении выглядит очень странно. Отладчик определенно показывает счетчик как ноль. Я подозреваю, что какая-то странная проблема сборки может маскировать истинную причину. –

+0

@MatthewWatson: Я думаю, что всплывающая подсказка показывает счетчик как 0, потому что она была 1 до того, как была введена инструкция if, после чего она уменьшилась (текущая строка после декремента). Другая подсказка imho оценивается при наведении курсора мыши, поэтому в этот момент времени 'counter> 0'' 'false' – Gorgsenegger

1

Если это однопоточное приложение без какого-либо другого кода, изменяющего counter, то наиболее вероятным объяснением является то, что Lights просто недостаточно. Например, если counter является 1 (который, я думаю, вы согласитесь, > 0 - так что тест if пройдет), и Lights является массив нулевой длины, то Lights[i] (Lights[0]) поднимет это исключение - или если counter составляет 200, но Lights.Length - 199 (или меньше) - в качестве Lights[i]() находится за пределами диапазона 0 - 198.

Проверить Lights.Length.

+0

Да, вот что я подумал! Но когда я посмотрел сообщение об ошибке в отладчике, которое было опубликовано, я стал очень неуверенным! (Я почему-то не могу пересоздать ссылку ...) –

0

попробовать, как этот

int i=0; 
if (counter > 0) 
{ 
Console.WriteLine("counter-1 is groter dan 0"); 
i = counter - 1; 
Lights[i].setState(0); 
} 
Смежные вопросы