为什么整数属性有时会返回一个0? [英] Why would an integer property sometimes return a 0?

查看:437
本文介绍了为什么整数属性有时会返回一个0?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



我有一个使用包含配置值的属性一类的应用程序。大部分的属性在应用程序中使用的表达式。该值被设定为启动和应用程序的主体部分运行的同时不改变



 私人诠释_TimerInterval; 
公众诠释TimerInterval {{返回_TimerInterval; }}

私人诠释_Factor1;
公众诠释因子1 {
集合{
_Factor1 =价值;
_TimerInterval = _Factor1 * _Factor2;
}
{返回_Factor1; }
}

私人诠释_Factor2;
公众诠释因子2 {
集合{
_Factor2 =价值;
_TimerInterval = _Factor1 * _Factor2;
}
{返回_Factor2; }
}



我发现,很少返回的值是显然为零,​​因为一个异常

 异常消息:0不是间隔的有效值。 间隔必须大于0 
异常目标站点更大:set_Interval



调用代码看起来这石灰:

  exitTimer.Interval = _config.TimerInterval; 



该程序是多线程的,但在调用个人财产只在一个线程中使用。类的其他属性被称为在其它线程。我看到的具有类似性质的其他计时器的问题。



如果我捕获该异常,然后重试它的工作任务。



难道还有什么在我的定时器发生,将造成比的财产返还为零的execption



更新#1 - 被要求更多的代码



每个字段定义为一个 cfXXX (配置域)不变。这将确保我们不会拼错字段名称。每个属性对应的默认值被定义为 DefXXX 。在 PareseXXX 函数( parseInt函数在此示例中)接受从配置查找字符串值,并将其转换为相应的值输入或提供的默认,如果它失败。 。失败是从缺失的XML记录(新配置选项),或者一个被错误地编辑



代码加载初始配置数据:

  //主窗体
公共fMain()
{
的InitializeComponent();
配置=新ConfigData();
config.LoadConfig();
//初始化其他
}

// ConfigData类

// XML配置字段名
私人常量字符串cfFactor1 =因子1
私人常量字符串cfFactor1 =因子2;
私人常量字符串cfFactor3 =Factor3;
私人常量字符串cfFactor4 =因子-4

//默认值
私人const int的DefFactor1 = 1;
私人const int的DefFactor2 = 50;
私人const int的DefFactor3 = 1;
私人const int的DefFactor4 = 25;

公共无效LoadConfig()
{
因子1 = parseInt函数(ConfigurationManager.AppSettings [cfFactor1],DefFactor1);
因子2 = parseInt函数(ConfigurationManager.AppSettings [cfFactor2],DefFactor2);
Factor3 = parseInt函数(ConfigurationManager.AppSettings [cfFactor3],DefFactor3);
因子-4 = parseInt函数(ConfigurationManager.AppSettings [cfFactor4],DefFactor4);
}

INT parseInt函数(字符串numberString,INT aDefault = 0)
{
INT结果;
如果{
结果= aDefault(int.TryParse(numberString,出结果)!);
}
返回结果;
}


解决方案

问题是前提错了。失败的性能实际上是漂浮和不是整数。尴尬。正如预期的那样增加锁的治愈问题的项目的属性。整数定时器从未失败过。



我会刚刚删除的问题,在这一点上,但它已经有了答案。所以,让它成为上双重检查的假设一个教训。


[Edit: I realized that the parameter that is failing is actually a double and not an integer. None of the integer timers fail according to the logs. Most of the timers and parameters are integers, but not all. Doubles are not atomic and the lack of locking may be the issue after all.]

I have an application that uses a class that contains properties for configurable values. Most of the properties being used in the app are derived. The values are set at start up and not changed while the main portion of the application is running.

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; }
}

I find that very rarely the value returned is apparently zero because of an exception.

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

The calling code looks lime this:

exitTimer.Interval = _config.TimerInterval;

The program is multi-threaded but the call to the individual property is only used in one thread. Other properties of the class are called in other threads. I do see the issue on other timers with similar properties.

If I trap the exception and retry the assignment it works.

Could there be something happening at my timer that would cause the execption other than the property returning zero?

Update #1 - More code was requested

Each field is defined as a cfXXX (Configuration Field) constant. This ensures we don't misspell the field names. A corresponding default value for each property is defined as DefXXX. The PareseXXX functions (ParseInt in this sample) accepts the string value from the configuration lookup and converts it to the corresponding value type or the provided default if it fails. Failure would be from a missing XML record (new configuration option) or one that was incorrectly edited.

Code to load initial configuration data:

// 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;
}

解决方案

The problem was that the premise was wrong. The properties that failed were actually floats and not integers. Embarrassing. As expected adding locks to the properties for those items cured the problem. The integer timers never failed.

I would have just deleted the question at this point, but it already has answers. So let it be a lesson on double checking assumptions.

这篇关于为什么整数属性有时会返回一个0?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆