您正在从多个线程访问共享变量。这可能是一种竞争条件,其中一个线程引发了错误,但当调试器捕获并附加错误时,变量的值已更改。
您需要考虑实现同步逻辑,例如锁定共享变量等。
Edit:回答您的编辑:
您无法真正告诉计时器不要滴答(当然可以,但是您会开始和停止,甚至在调用 Stop 之后,您可能仍然会收到更多事件,具体取决于它们的调度速度)。也就是说,您可以查看 Interlocked 命名空间并使用它来设置和清除 IsBusy 标志。如果您的 tick 方法触发并发现您已经在工作,它只会在该轮中等待,等待未来的 tick 来处理工作。我不会说这是一个很好的范例,但它是一个选择。
我指定使用 Interlocked 类而不是仅使用共享变量的原因归结为您可以同时从多个线程访问这一事实。如果您不使用互锁,您可能会得到两个勾号,既检查值又得到答案,他们可以在翻转标志以阻止其他人进入之前继续进行。你也会遇到同样的问题。
同步对共享数据成员的访问的更传统方法是使用锁定,但是您很快就会遇到tick事件触发太快的问题,并且它们将开始支持您。
Edit 2:要回答有关在多个线程上将数据与共享变量同步的方法的问题,这实际上取决于您具体在做什么。我们对您的应用程序正在执行的操作只有一个非常小的窗口,因此我将从所有评论和答案中将其拼凑在一起,希望它能为您的设计选择提供信息。
下面是伪代码。这是基于您提出的问题,该问题表明您不需要在每个刻度上都进行工作。蜱虫本身并不重要,它只需要不断地进来。基于这个前提,我们可以使用标记系统来检查您是否忙碌。
...
Timer.Start(Handle_Tick)
...
public void Handle_Tick(...)
{
//Check to see if we're already busy. We don't need to "pump" the work if
//we're already processing.
if (IsBusy)
return;
try
{
IsBusy = true;
//Perform your work
}
finally
{
IsBusy = false;
}
}
在这种情况下,IsBusy 可能是一个易失性布尔值,可以通过以下方式访问它联锁 http://msdn.microsoft.com/en-us/library/system.threading.interlocked%28v=vs.110%29.aspx命名空间方法,可能是锁定等。您选择什么取决于您。
如果这个前提不正确,并且您实际上必须在计时器的每个滴答声中进行工作,那么这对您不起作用。你正在扔掉忙碌时进来的蜱虫。如果您想保留每个进入的时钟周期,您需要实现一个同步队列。如果您的频率很高,您必须小心,因为您最终会溢出。