gpt4 book ai didi

.net - Thread.Sleep导致Timer的回调延迟

转载 作者:行者123 更新时间:2023-12-03 13:14:44 25 4
gpt4 key购买 nike

在这里,我的测试代码中有一个奇怪的行为,该代码非常简单,创建了一堆具有相同模式的Timer:在所有回调中添加 Thread.Sleep 。然后几乎在同一时间启动计时器,然后可以看到一些计时器的回调是延迟了

public class StrangTimerTesting
{
public int callback_EnteredTimes;

// for avoid timers get GCed.
private List<System.Timers.Timer> timerContainer = new List<System.Timers.Timer>();

public void Go()
{
for (var i = 0; i < 5; i++)
{
var displayTimer = new System.Timers.Timer(1000);
displayTimer.Elapsed += (a, b) =>
{
Interlocked.Increment(ref this.callback_EnteredTimes);
var initalTime = DateTime.Now.ToString("HH:mm:ss.ffff");
Console.WriteLine("entered times: " + callback_EnteredTimes + ", intial@" + initalTime);
displayTimer.Stop();

// why this Sleep cause some callback delayed to be called????
Thread.Sleep(6000);
};

displayTimer.Start();
timerContainer.Add(displayTimer);
}
}
}

我想虽然在不同的线程池线程上,所有回调几乎都将在同一时间被调用,但是测试结果显然不支持此操作,如果我删除了Thread.Sleep,那么有 2秒间隔,那么一切很好有人可以指出原因吗?

EDIT1:这是测试程序的结果:

*输入时间:1,初始@ 08:43:29.4732

输入的时间:2,初始@ 08:43:29.4762

输入的时间:3,初始@ 08:43:30.4763

输入的时间:4,intial @ 08:43:30.9764

输入的时间:5,初始@ 08:43:31.4764 *

我笔记本电脑中的MinThreads数是2。

最佳答案

您创建了一个firehose问题。您有5个计时器,每个计时器在1秒上滴答作响,其Elapsed事件处理程序将休眠6秒钟。您希望您的程序实际上每秒将添加5个线程,这些线程需要30秒才能完成工作。或者换种说法,每分钟增加300个线程,仅完成10个线程。

如果任其发展,这将不会有一个好的结果。说得客气一点。线程是非常昂贵的操作系统资源。超过5个句柄,它消耗了1 MB的虚拟内存。在32位进程中,程序仅用7分钟即可消耗所有可用内存并因OutOfMemoryException崩溃。

.NET不会让您这样做,除非您不作斗争。它使用的对策是您观察到的对策,它不允许您启动那么多线程。这有意减慢了允许启动的新程序的速度。它将每秒仅在您的计算机上允许2个新线程。

这是ThreadPool调度程序的工作。它试图将正在执行的TP线程数减少到设置的最小值。在您的计算机上,最小数量为2,即您拥有的内核数。让它运行超过2个并没有多大意义,操作系统将不得不做更多的工作才能使这些线程有机会运行,并在它们之间进行上下文切换。实际上,减慢它们的速度,理想的数字是2,因此它们有很大的机会不受限制地访问处理器并尽快完成工作。

但是,ThreadPool调度程序不知道线程在做什么,它对正在执行的代码了解得很不完善。它不知道您的线程实际上根本没有完成任何工作,只是在 sleep 。为此,有一个对策。每秒两次,如果 Activity 线程未完成,它将覆盖其默认调度策略,从而允许额外的线程启动。如果绝对必要,此过程将继续,直到达到设置的最大允许值。这个数字非常高,在您的计算机上应该为500左右。

这是一个非常有效的算法,它将防止您的程序在7分钟后爆炸。它仍然会爆炸,但这将需要非常非常长的时间。最终,由于拥有TP调度程序无法处理的数百万个TP线程启动请求,您最终仍然获得OOM。否则,您编写不合理的程序时总会期望得到不合理的结果。

关于.net - Thread.Sleep导致Timer的回调延迟,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19723225/

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