C# .NET 4.0 System.Timers.Timer似乎在一段时间后不执行已用事件
我有一个需要全天候运行的类。它使用Timers.Timer在计算的时间间隔内执行经过的事件。经过一段时间(3-5天)后,计时器将停止执行经过的事件。并非所有用户都会出现这种情况,有4或5个用户报告了这种情况C# .NET 4.0 System.Timers.Timer似乎在一段时间后不执行已用事件,c#,.net,C#,.net,我有一个需要全天候运行的类。它使用Timers.Timer在计算的时间间隔内执行经过的事件。经过一段时间(3-5天)后,计时器将停止执行经过的事件。并非所有用户都会出现这种情况,有4或5个用户报告了这种情况 public class MyClass : IMyClass { public static MyClass thisMyClass; private Timer myTimer; PERIOD = 60000; private SomeHighResol
public class MyClass : IMyClass
{
public static MyClass thisMyClass;
private Timer myTimer;
PERIOD = 60000;
private SomeHighResolutionClass _lapseTimer;
private double _timeToNextExec
{
get
{
double lapseTime = _lapseTimer.LapseTime();
double next = PERIOD - lapseTime;
if (next > 0)
{
return next;
}
else
{
return 1;
}
}
}
private MyClass()
{
myTimer = new Timer(PERIOD);
myTimer.Elapsed += new ElapsedEventHandler(myTimer_Elapsed);
// Only raise the event the first time Interval elapses.
myTimer.AutoReset = false;
myTimer.Enabled = true;
}
public void myTimer_Elapsed(Object source, ElapsedEventArgs e)
{
LogHere("Elapse started"); // Entry log
try
{
try
{
_lapseTimer.Start();
DoStuffHere();
}
catch (Exception ex)
{
LogException(ex);
}
}
finally
{
myTimer.Interval = _timeToNextExec;
LogHere("restarting timer interval " + myTimer.Interval); // Finally Log
myTimer.Start();
}
}
private void DoStuffHere()
{
//some processing that could take 1-2 or more seconds to process
}
public static void Initialize()
{
thisMyClass = new MyClass();
}
public static IMyClass Interface
{
get { return thisMyClass as IMyClass; }
}
}
在另一个类上,这是静态初始化的
MyClass.Initialize()
计时器间隔是可变的。它基于dostufhere()的运行时间代码>。若它花费的时间超过了PERIOD,那个么只要dostufhere完成,它仍然会被执行
根据我们接收到的数据,已运行事件已完成,并且条目日志和最终日志都已成功记录。
我们还可以确定,根据我们接收到的内存转储和来自内存转储的信息,计时器已重新启动/启用,并且计时器已启用,应触发已过但未触发。内存转储是在我们已经观察到dostufhere()
未被执行时获得的。登录LogExceptions(),也没有异常代码>
内存转储中的计时器信息
70dcf7dc 40001e0 4 System.Object 0 instance 00000000 __identity
703d7618 40002c3 8 ...ponentModel.ISite 0 instance 00000000 site
703d6b74 40002c4 c ....EventHandlerList 0 instance 00000000 events
70dcf7dc 40002c2 cc System.Object 0 static 00000000 EventDisposed
70dca574 4002dbd 10 System.Double 1 instance 55949.118673 interval
70dd6820 4002dbe 2c System.Boolean 1 instance 1 enabled
70dd6820 4002dbf 2d System.Boolean 1 instance 0 initializing
70dd6820 4002dc0 2e System.Boolean 1 instance 0 delayedEnable
703ceb80 4002dc1 18 ...apsedEventHandler 0 instance 0246fc8c onIntervalElapsed
70dd6820 4002dc2 2f System.Boolean 1 instance 0 autoReset
703d5fcc 4002dc3 1c ...SynchronizeInvoke 0 instance 00000000 synchronizingObject
70dd6820 4002dc4 30 System.Boolean 1 instance 0 disposed
70dcacfc 4002dc5 20 ...m.Threading.Timer 0 instance 0246fcb8 timer
70dcb07c 4002dc6 24 ...ing.TimerCallback 0 instance 0246fc6c callback
70dcf7dc 4002dc7 28 System.Object 0 instance 0246fcac cookie
我真的很困惑和不知所措。请帮帮我
--更新-有关线程的附加信息——在计时器停止后,线程数量似乎会增加,因此这可能不是导致问题的原因
0:000> !threads -live
ThreadCount: 809
UnstartedThread: 790
BackgroundThread: 14
PendingThread: 790
DeadThread: 1
Hosted Runtime: no
PreEmptive GC Alloc Lock
ID OSID ThreadOBJ State GC Context Domain Count APT Exception
0 1 d4c 012be0a0 2006020 Enabled 00000000:00000000 012b7310 0 STA
2 2 d54 012c9dd0 b220 Enabled 00000000:00000000 012b7310 0 MTA (Finalizer)
3 3 d60 0131a0c0 100a220 Enabled 00000000:00000000 012b7310 0 MTA (Threadpool Worker)
4 4 d64 01331ef0 b220 Enabled 00000000:00000000 012b7310 0 MTA
6 6 d70 01337348 1000220 Enabled 00000000:00000000 012b7310 0 Ukn (Threadpool Worker)
7 7 d8c 0133f100 2000220 Enabled 00000000:00000000 012b7310 0 Ukn
9 a f90 06c2c948 2000220 Enabled 00000000:00000000 012b7310 0 Ukn
10 b 9a8 06c33f48 200b020 Enabled 00000000:00000000 012b7310 0 MTA
11 c 584 06c34450 200b020 Enabled 00000000:00000000 012b7310 0 MTA
12 d 5f4 06c35758 200b020 Enabled 00000000:00000000 012b7310 0 MTA
13 12 970 06ca6d08 2000220 Enabled 00000000:00000000 012b7310 0 Ukn
14 e 1254 06ca8b38 2000220 Enabled 00000000:00000000 012b7310 0 Ukn
15 13 12f0 06ca9548 2000220 Enabled 00000000:00000000 012b7310 0 Ukn
16 5 10ec 06ca7210 2000220 Enabled 00000000:00000000 012b7310 0 Ukn
17 f 1d90 06cac290 a009220 Enabled 259e45ac:259e4fe8 012b7310 0 MTA (Threadpool Completion Port)
19 19 1124 06ca7718 8009220 Enabled 258f90c4:258fafe8 012b7310 0 MTA (Threadpool Completion Port)
20 8 1394 06ca9040 2000220 Enabled 00000000:00000000 012b7310 0 Ukn
22 322 21d4 13698f50 2000220 Enabled 259e6394:259e6fe8 012b7310 0 Ukn
干杯!蒂亚 如果您的系统实时性不是很严格,您可以尝试
if (next > 10)
{
return next;
}
else
{
return 10;
}
你的线程有问题
应用程序中不应有约800个线程(!)。此外,他们似乎无法完全启动(出于某种原因)。可能是资源耗尽(可能是内存)。沉重的寻呼
找出为什么有这么多线程。可能您正在许多线程上运行大量的阻塞工作,或者将许多这样的工作项发布到线程池。在无法创建实例的情况下,如何使用此类?@HamletHakobyan,很抱歉,我更新了上面的代码,以显示如何使用MyClass.Initialize()静态初始化此类
要访问静态实例,有一个static IMyClass接口
对象返回static thisMyClass
您是否确保(从转储)间隔设置为正确的值?您的线程池是否在几天后就被充分利用了?比如250个线程在等待?然后,计时器的滴答声无法通过。@usr,是的,转储显示Interval
是55949.118673
。关于线程,请参见上面的更新。总之,有809个线程,790个未启动,1个已死亡,等等。这意味着有什么不好的吗?谢谢@Lichdr,这可能是一个。但是,基于内存转储,下一个计时器应该在55949.118673毫秒后触发(instance 55949.118673 interval
)55949.118673,这意味着dostufhere()大约在4秒后完成。谢谢。这真的很有启发性,我确实有内存转储,但我真的不知道从哪里开始分析。当我在上面的评论中问到“这意味着什么坏事吗?”时,我真的觉得自己很“傻”:P。我自嘲了一下。谢谢我自己从来没有做过垃圾分析,所以我不知道。首先,我会对所有启动线程或将工作排队到池中的位置进行代码检查。我认为转储中的调用堆栈不会有很大帮助,因为线程到目前为止都无法启动。不过值得一试。你是对的@usr。哦,孩子。当myTimer因为线程太多而被占用时(如您所述),内存就会增加。但是我想知道为什么线程的数量会激增到这个数字。我通常有20-30个(或者忙的时候有50个)。让我再告诉你。ThanksHi@usr,我们收到了用户关于最近计时器故障的新性能日志。这个问题似乎不是由线程数引起的。当计时器无法运行时,进程中当前的线程数至少为(22个线程),在计时器无法运行一段时间后,未启动的线程数最终会增加。还有什么想法吗?