簡體   English   中英

.NET 4.0 System.Timers.Timer似乎在一段時間后沒有執行經過的事件

[英].NET 4.0 System.Timers.Timer seems to not execute the elapsed event after some time

我有一個需要全天候運行的課程。 它使用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();的經過時間DoStuffHere(); 如果它需要比PERIOD更長的時間,那么只要DoStuffHere完成它仍然會被執行。

根據我們收到的數據,已完成的事件已完成,並且條目日志和終止日志都已成功記錄。 我們也確定根據我們收到的內存轉儲重新啟動/啟用Timer,並根據內存轉儲中的信息啟用定時器,並且應該觸發已經過去但是沒有。 當我們已經觀察到DoStuffHere()沒有被執行時,獲得了內存轉儲。 LogExceptions();記錄的也沒有異常也沒有異常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!

你的線程有問題。 解釋特定計數器的含義。

應用程序中不應該有~800個線程(!)。 此外,他們似乎無法完全開始(出於某種原因)。 它可能是資源枯竭(可能是內存)。 重撥。

找出有這么多線程的原因。 也許你在許多線程上運行了很多阻塞工作,或者將很多這樣的工作項發布到線程池。

如果您的系統實時不是很嚴格,那么您可以嘗試

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM