线程休眠不起作用!

3
考虑以下代码,它在某个类的每次实例化时被执行:
private void StartUpdateThread()
{
    runUpdateThread = true;

    Thread thread = new Thread(new ThreadStart(UpdateUsages));
    thread.Priority = ThreadPriority.BelowNormal;
    thread.Start();
}

public void UpdateUsages()
{
    DateTime updateDateTime = DateTime.Now;

    while (runUpdateThread)
    {
        if (updateDateTime <= DateTime.Now)
        {
            _cpuUsage.Add(DateTime.Now, GetCPUUsage());

            if (_cpuUsage.Count == 61)
                _cpuUsage.Remove(_cpuUsage.ElementAt(0).Key);

            _ramUsage.Add(DateTime.Now, GetRamUsage());

            if (_ramUsage.Count == 61)
                _ramUsage.Remove(_ramUsage.ElementAt(0).Key);

            updateDateTime = DateTime.Now.AddSeconds(15);
        }

        Thread.Sleep(15000);
    }
}

在每个字典中添加2或3个值后,它会抛出"字典中已经存在相同键的元素"。这应该是不可能的,因为我在每个循环之后都进行了Sleep。

我尝试通过添加updateDateTime变量来解决这个问题,但没有成功。

我已经想尽了办法。有人可以帮助我或解释一下这是如何发生的吗?

谢谢。


4
另外提醒一下,您的 DateTime.Now 调用可能会返回不同的时间。您需要调用它一次,将值保存在一个变量中,然后在您的 while 循环中重复使用,至少要这样做。 - Adam Lear
1
为了获得好的答案,请努力发布好的问题。请回答以下问题,可以通过文本或扩展示例代码来回答:您是否从其他线程访问数据结构?如果是,是只读访问还是读写访问?"_cpuUsage"和"_ramUsage"如何定义?您是启动多个这样的线程还是只有一个? - Lasse V. Karlsen
考虑到这一点,那么,在不同的循环中如何可能出现该异常? - pedrodbsa
考虑什么?“不同的循环”吗?你在多个线程上运行那段代码了吗? - Lasse V. Karlsen
我正在从其他线程读取_cpuUsage和_ramUsage.. 写入只在那个while循环中完成。 - pedrodbsa
显示剩余4条评论
1个回答

3
< p>请问_cpuUsage_ramUsage是否是静态的?或者您可能已经将它们两个赋了相同的值?如果您能提供一个简短但完整的程序来演示问题,那将使事情更加清晰。

顺便说一句,您似乎希望使用ElementAt(0)来从字典中删除最早的条目,但这并不保证。

从您所做的事情来看,您最好使用LinkedList<Tuple<DateTime,long>>或类似的数据结构。


如果类型是字典,那么不会进行其他写入操作,即使代码有错误,他也能看到这种类型的错误吗? - Lasse V. Karlsen
@Lasse:如果有多个线程访问同一个字典(如果变量是静态的,并且存在多个实例),那么这可能会解释一些问题。查看更多代码肯定会有所帮助。 - Jon Skeet
1
是的,如果有多个线程在写入,他很可能会尝试复制键,或者他可能会使状态损坏到无法挽回的地步。 - Lasse V. Karlsen
啊,我没注意到,“在每个实例上”。 - Lasse V. Karlsen
如果这些字典是共享的,那么他需要锁定,没有其他办法。 - Lasse V. Karlsen
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接