为什么整数属性有时会返回0?

时间:2013-09-30 13:06:05

标签: c# multithreading c#-4.0 properties timer

[编辑:我意识到失败的参数实际上是一个双精度而不是一个整数。根据日志,整数计时器都不会失败。大多数计时器和参数都是整数,但不是全部。双打不是原子的,毕竟缺乏锁定可能是个问题。]

我有一个应用程序,它使用包含可配置值属性的类。应用程序中使用的大多数属性都是派生的。这些值在启动时设置,在应用程序的主要部分运行时不会更改。

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 - 请求了更多代码

每个字段定义为cfXXX(配置字段)常量。这可以确保我们不会拼错字段名称。每个属性的相应默认值定义为DefXXXPareseXXX函数(此示例中为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;
}

3 个答案:

答案 0 :(得分:2)

问题在于前提是错误的。失败的属性实际上是浮点数而不是整数。尴尬。正如预期的那样,为这些项目的属性添加锁定可以解决问题。整数计时器永远不会失败。

我刚刚删除了这个问题,但它已经有了答案。因此,让它成为双重检查假设的一课。

答案 1 :(得分:1)

如果要为每个实例分配这些因子一次,在使用实例之前...在构造函数中执行此操作。

如果要在创建任何实例之前为类型分配这些因子一次...在静态构造函数中执行此操作。

不要在线程之间共享可变实例。

答案 2 :(得分:0)

当设置了Factor1或Factor2时,_TimerInterval为0。

x * 0 = 0