gpt4 book ai didi

c# - 具有自动重置功能的计时器导致 System.OutOfMemoryException

转载 作者:行者123 更新时间:2023-11-30 14:31:11 28 4
gpt4 key购买 nike

我有以下代码,它在某个需要每 200 毫秒监视一次的表上运行“select”

timerMonitoreoOrdenes = new System.Timers.Timer(FRECUENCIA_MONITOREO_ORDENES);
timerMonitoreoOrdenes.Elapsed += new ElapsedEventHandler(timerMonitoreoOrdenes_Elapsed);
timerMonitoreoOrdenes.Enabled = true;
timerMonitoreoOrdenes.AutoReset = true;

timerMonitoreoOrdenes_Elapsed 方法中,我运行了一个返回 DataSet 的存储过程对于每一行,我都创建了一个存储在内存 Queue

中的新对象

该程序设计为一直运行(如 Windows 服务),但在程序运行几个小时后我收到此异常

   System.OutOfMemoryException: 
in System.Threading.ExecutionContext.CreateCopy()
in System.Threading._TimerCallback.PerformTimerCallback(Object state)

我这样做的原因是因为有一个外部程序在 status=0 的数据库上插入记录,我需要获取这些记录,处理它们并设置 status=1。有一些线程正在从队列中获取记录

重要的是,这是一个实时交易应用程序,信息延迟 1 秒太高

  • 我想知道 System.OutOfMemoryException 是否因为计时器自动重置而被抛出?
  • 我应该创建一个 Thread 还是使用 Thread.Sleep 而不是 Timer 来检查由另一个进程插入的某些记录?

最佳答案

当然,这是很有可能的。使用 AutoReset = true 滴答作响的 Timer 是一个滴答作响的定时炸弹。如果间隔太短,事情就会大错特错。使用 200 毫秒是非常冒险的,数据库更新查询很容易花费比这更长的时间。如果您要查找的列未编入索引,则尤其如此。

您的 Elapsed 事件处理程序将再次运行,即使前一个事件处理程序未完成。在另一个线程池线程上。每个线程将消耗 1 兆字节的内存,加上查询和处理所需的任何内存。这只是继续,创建更多的线程。线程池管理器将努力限制这一点,但允许运行的最大线程数非常高。高到足以导致任意代码最终因 OOM 而失败。

使用 AutoReset = false 并在 Elapsed 事件处理程序结束时再次调用 Start()。并使用至少接近实际处理时间的合理间隔。并在该列上添加索引,这样数据库引擎就不必查看表中的每个记录。

关于c# - 具有自动重置功能的计时器导致 System.OutOfMemoryException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20904634/

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