非常奇怪和严重的多线程不一致问题c#
我有一个非常简单的监视程序,有2个线程。一个线程正在更新一个长变量,另一个线程正在读取该变量。如果距离上次更新超过X秒,则发出警报。问题是有时(或多或少每天发生一次)第二个线程读取变量的陈旧值。
有时它是3秒前的陈旧值(即第一个线程更新了长变量,但是3秒后其他线程没有获得新值)
我正在使用锁,以避免多线程缓存问题。我也尝试过Volatile,Interlock,volatileRead等,但没有任何帮助。该类通过COM通过VB 6程序启动。该程序非常简单,所以我认为它是C#中的一个错误(可能与COM相关)。这是程序:
你能帮帮忙吗?
public class WatchDog
{
long lastDate = DateTime.Now.ToBinary();
private object dateLock = new object();
bool WatchdogActive = true;
int WatchdogTimeoutAlert = 5;
int WatchdogCheckInterval = 6000;
private void WatchdogThread()
{
try
{
while (WatchdogActive)
{
lock (dateLock)
{
DateTime lastHB = DateTime.FromBinary(lastDate);
if ((DateTime.Now.Subtract(lastHB).TotalSeconds > WatchdogTimeoutAlert))
{
Console.WriteLine(" last Date is " + lastDate);
}
}
Thread.Sleep(WatchdogCheckInterval);
}
}
catch (Exception Ex)
{
}
}
private void OnHeartbeatArrive(long heartbeatTime)
{
lock (dateLock)
{
lastDate = heartbeatTime;
Console.WriteLine(" Got Heartbeat lastDate " + lastDate);
}
}
}
没有找到相关结果
已邀请:
2 个回复
剿畦缄饥小
这不起作用,WatchdogActive没有声明为volatile。在Release版本中,变量很可能存储在CPU寄存器中,它永远不会看到其他线程对变量所做的更新。换句话说,即使您将其关闭,看门狗仍然会处于活动状态。 你应该在这里使用ManualResetEvent,它的WaitOne(int)方法会自动处理Sleep(),并为你提供更快的线程终止作为奖励。 一些奇怪的不一致。你引用了3秒的失败,但你只检查> = 5秒。 Sleep()比检查更长,可以错过故障。您似乎喜欢空的catch块,总是为代码在没有任何诊断的情况下无法工作提供了很好的机会。我猜我们没有看到真正的代码,这使得很难看到细微的线程问题。从假设这不是C#中的错误开始工作。
购藏盗码韦
为什么你通过'long'而不是DateTime?