2013-09-30 4 views
5

[Edit: Я понял, что параметр, который терпит неудачу, на самом деле является двойным, а не целочисленным. Ни один из целых таймеров не работает в соответствии с журналами. Большинство таймеров и параметров являются целыми числами, но не все. 0:Почему целочисленное свойство иногда возвращает 0?

У меня есть приложение, которое использует класс, содержащий свойства для настраиваемых значений. У меня есть приложение, которое использует свойства для настраиваемых значений. Выводятся большинство свойств, используемых в приложении. Значения устанавливаются при запуске и не изменяются во время работы основной части приложения.

private int _TimerInterval; 
public int TimerInterval { get { return _TimerInterval; } } 

private int _Factor1; 
public int Factor1 { 
    set { 
    _Factor1 = value; 
    _TimerInterval = _Factor1 * _Factor2; 
    } 
    get { return _Factor1; } 
} 

private int _Factor2; 
public int Factor2 { 
    set { 
    _Factor2 = value; 
    _TimerInterval = _Factor1 * _Factor2; 
    } 
    get { return _Factor2; } 
} 

Я нахожу, что очень редко возвращаемое значение, по-видимому, является нулевым из-за исключения.

Exception Message: '0' is not a valid value for 'Interval'. 'Interval' must be greater than 0. 
Exception Target Site: set_Interval 

код Вызывающий выглядит извести это:

exitTimer.Interval = _config.TimerInterval; 

Программа многопоточная, но призыв к индивидуальной собственности используется только в одном потоке. Другие свойства класса вызывают в других потоках. Я вижу проблему с другими таймерами с аналогичными свойствами.

Если я улавливаю исключение и повторяю задание, оно работает.

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

Обновление # 1 - больше коды была предложена

Каждого поля определяются как (Field Configuration) в cfXXX постоянная. Это гарантирует, что мы не будем пропускать имена полей. Соответствующее значение по умолчанию для каждого свойства определяется как DefXXX. Функции PareseXXX (ParseInt в этом примере) принимают строковое значение из поиска конфигурации и преобразуют его в соответствующий тип значения или предоставленный по умолчанию, если он терпит неудачу. Ошибка будет связана с отсутствующей записью XML (новая конфигурация) или с некорректным редактированием.

код для загрузки исходных данных конфигурации:

// Main Form 
public fMain() 
{ 
    InitializeComponent(); 
    config = new ConfigData(); 
    config.LoadConfig(); 
    // Other initializations 
} 

//ConfigData Class 

// XML config field names 
private const string cfFactor1 = "Factor1"; 
private const string cfFactor1 = "Factor2"; 
private const string cfFactor3 = "Factor3"; 
private const string cfFactor4 = "Factor4"; 

//Default values 
private const int DefFactor1 = 1; 
private const int DefFactor2 = 50; 
private const int DefFactor3 = 1; 
private const int DefFactor4 = 25; 

public void LoadConfig() 
{ 
    Factor1 = ParseInt(ConfigurationManager.AppSettings[cfFactor1], DefFactor1); 
    Factor2 = ParseInt(ConfigurationManager.AppSettings[cfFactor2], DefFactor2); 
    Factor3 = ParseInt(ConfigurationManager.AppSettings[cfFactor3], DefFactor3); 
    Factor4 = ParseInt(ConfigurationManager.AppSettings[cfFactor4], DefFactor4); 
} 

int ParseInt(string numberString, int aDefault = 0) 
{ 
    int result; 
    if (!int.TryParse(numberString, out result)) { 
    result = aDefault; 
    } 
    return result; 
} 
+1

как вы устанавливаете 'Factor1' и' Factor2'? –

+9

«Программа многопоточная ...» <- У вас проблемы. –

+4

Очевидно, что свойство _config.TimerInterval равно 0. Это типичный признак * threading race *, позволяющий начать поток * до того, как * _config будет полностью инициализирован. И, конечно, это может означать, что ваш конфиг просто плох или отсутствует. –

ответ

2

Проблема была в том, что помещение было неправильным. Сбой в свойствах был фактически плавающим, а не целым числом. Неловко. Как и ожидалось, добавление блокировок к свойствам для этих элементов устраняет проблему. Целочисленные таймеры никогда не прерывались.

Я бы просто удалил вопрос на этом этапе, но у него уже есть ответы. Так что пусть это будет урок по двойным проверкам допущений.

+0

+1 для подтверждения требуемого исправления и того, что вы узнали. Полезная обратная связь для меня, по крайней мере. – groverboy

0

_TimerInterval является 0, когда только Factor1 или Factor2 установлен.

х * 0 = 0

+0

Правда, но не в этом случае. –

+0

Функция LoadConfig только что установила Factor1 – user743414

+0

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

1

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

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

Не передавайте изменяемые экземпляры между потоками.

Смежные вопросы