.NET 4.0 System.Timers.Timer似乎在一段时间后没有执行经过的事件

时间:2014-10-23 05:11:27

标签: c# .net

我有一个需要全天候运行的课程。它使用Timers.Timer以计算的间隔执行已发生的事件。经过一段时间,3-5天后,计时器才会停止执行已过去的事件。这不会发生在所有用户中,有4或5个报告。

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()

计时器间隔是可变的。它基于DoStuffHere();的经过时间。如果它需要比PERIOD更长的时间,那么只要DoStuffHere完成它就会被执行。

根据我们收到的数据,已完成的事件已完成,并且条目日志和终止日志都已成功记录。 我们也确定根据我们收到的内存转储重新启动/启用Timer,并根据内存转储中的信息启用定时器,并且应该触发已经过去但是没有。当我们已经观察到DoStuffHere()没有被执行时,获得了内存转储。 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

我真的很困惑,也很无能为力。请帮帮我们

- 更新 - 有关线程的其他信息 - 在Timer停止后线程数似乎上升,因此可能不是导致我们出现问题的线程数。

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

干杯! TIA!

2 个答案:

答案 0 :(得分:2)

你的主题有问题。 An explanation of what the specific counters mean.

应用程序中不应该有~800个线程(!)。此外,他们似乎无法完全开始(出于某种原因)。它可能是资源枯竭(可能是内存)。沉重的传呼。

找出有这么多主题的原因。也许你在许多线程上运行了大量的阻塞工作,或者将很多这样的工作项发布到线程池。

答案 1 :(得分:0)

如果您的系统实时不是很严格,请尝试

if (next > 10)
        {
            return next;
        }
        else
        {
            return 10;
        }