gpt4 book ai didi

c# - 非常奇怪和严重的多线程不一致问题c#

转载 作者:行者123 更新时间:2023-11-30 22:42:12 25 4
gpt4 key购买 nike

我有一个非常简单的带有 2 个线程的看门狗程序。一个线程正在更新一个 long 变量,另一个线程读取该变量。如果距离上次更新超过 X 秒,则发出警报。问题是有时(每天或多或少发生一次)第二个线程读取变量的陈旧值。

有时它是 3 秒前的陈旧值(即第一个线程更新了 long 变量,但 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);
}
}
}

最佳答案

        while (WatchdogActive)

这不起作用,WatchdogActive 未声明volatile。在 Release 版本中,变量很可能存储在 CPU 寄存器中,它永远看不到其他线程对变量所做的更新。换句话说,看门狗仍将处于事件状态,即使您将其关闭也是如此。

您应该在此处使用 ManualResetEvent,它的 WaitOne(int) 方法会自动处理 Sleep() 并为您提供更快的线程终止作为奖励。

一些奇怪的不一致。您在 3 秒时引用失败,但您只检查 >= 5 秒。 Sleep() 比检查长,因此有可能错过失败。你似乎喜欢空的 catch block ,总是为代码在没有任何诊断的情况下无法工作提供了很好的机会。我猜我们没有查看真正的代码,这使得很难看到细微的线程问题。从假设这不是 C# 中的错误开始工作。

关于c# - 非常奇怪和严重的多线程不一致问题c#,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4537447/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com