【发布时间】:2011-05-31 01:29:48
【问题描述】:
我有一个非常简单的带有 2 个线程的看门狗程序。一个线程正在更新一个长变量,另一个线程读取该变量。并在距离上次更新超过 X 秒时发出警报。问题是有时(每天或多或少发生一次)第二个线程读取变量的陈旧值。
有时它是 3 秒前的旧值(即第一个线程更新了 long 变量,但 3 秒后另一个线程没有得到新值)
我正在使用锁,以避免多线程缓存问题。我还尝试了 Volatile、Interlock、volatileRead 等,但没有任何帮助。该课程通过 VB 6 程序通过 COM 启动。该程序非常简单,所以我认为这是 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);
}
}
}
【问题讨论】:
-
您可能需要提供一些关于如何调用
OnHeartbeatArrive()的信息,特别是如何确定传递给它的heartbeatTime。 -
要清楚,发布的代码是否与 WriteLine() 语句一起证明了问题?
-
@michael 当我通过 TCP 从服务器收到消息时,我使用 DateTime.Now.ToBinary() 调用 OnHeartbeatArrive。请注意,我打印相同的变量。我看到它从更新线程中更改了它的值,但我在读取线程中看到了一个旧值。
-
@Henk:是的。我使用控制台 writeLine 在更新后和读取中查看变量的值,然后我注意到读取器线程甚至在 3 秒内读取了一个旧值!在更新线程更新值并打印之后。
-
您使用的是什么 IDE。您是从 IDE 启动程序吗?
标签: c# .net multithreading volatile interlocked