2013-05-21 61 views
0

已解决:代码每10毫秒通过事件执行,增加了事件之间花费的时间来解决问题。C#false if语句正在使用

我遇到了一个不应该发生的奇怪的IndexOutOfRangeException。即使语句本身是'错误',也正在使用if语句中的代码。这是一个已知的问题吗?如果是这样,我该如何解决这个问题?

当计数器(int)为0时发生错误,因此请求array灯光中的element -1

代码:

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

从其他线程访问'counter'吗? –

+0

我很抱歉,但那不可能是正确的。如果if语句为false,那么语句中的代码将不会被执行,除非您有多线程问题。你可以发布更多的代码,以便我们看到你在做什么? –

+0

错误的图像可以在这里看到:http://s13.postimg.org/a0frmariv/indexoutofrange.jpg我也很惊讶地看到它..应用程序是一个单线程应用程序和计数器是一个私人变量。 – Simon

回答

0

定时器触发的事件每10ms。这创造的posibility:

  • 程序事件A期间获得if语句里面
  • 一个新的事件B被解雇和CPU照顾事件B的
  • 事件B改变计数器为负值,从而使if语句为假。
  • CPU将更改为处理事件A.
  • 程序现在位于if语句中,即使if语句本身为false也是如此。

该问题已经通过减少事件发生次数来解决。

+0

问题还没有解决这只是可能会发生的 –

+0

使用互斥锁来锁定语句可能是一个选项,但这将需要我锁定每一个可能导致问题的陈述。该计划旨在运行在特定的硬件上,因此它的局限性是已知的,并且在项目期间不会改变。 – Simon

1
除非

计数器被访问/操纵在一个多线程的方式 - 这应该是一个不可能的状态。

你总是可以尝试使分配&检查在同一个地方:

var index = 0; 

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

这只会让代码更难阅读,也更难以调试imho。它对线程安全没有任何帮助。 – Steve

0

如果没有其他线程在后台改变counter,那么唯一可能的解释是,​​集合大小为零。

尝试在访问元素前检查Lights的长度。

+0

但这是否解释代码正在执行,尽管条件评估为false – tariq

+0

@tariq我不相信这是发生了什么。我认为实际发生的事情是'Lights []'具有零大小。但我同意链接图片中的信息看起来很奇怪。调试器肯定将计数器显示为零。我怀疑一些奇怪的构建问题可能掩盖了真正的原因。 –

+0

@MthetheWWatson:我认为工具提示显示计数器为0,因为在if语句输入之前它是1,然后递减(当前行是递减后的行)。其他工具提示imho正在鼠标悬停进行评估,所以在那个时间点'counter> 0'是'false' – Gorgsenegger

1

如果这是一个没有任何其他代码变异的单线程应用counter,那么最可能的解释是Lights不够长。例如,如果counter1(这是,我想你会同意,> 0 - 所以if测试将通过),并Lights是一个长度为零的数组,然后Lights[i]Lights[0])将引发此异常 - 或者,如果counter200,但是Lights.Length199(或更少) - 如Lights[i]Lights[199])在范围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); 
}