0

I have an UCMA console app and I want it to report "I am alive" signal by writting current timestamp to the database. To do that I use timer:

 public static void Main(string[] args)
{
   Random r = new Random();
   System.Threading.TimerCallback TimerDelegate = new System.Threading.TimerCallback(TimerCallBack);
   Timer TimerItem = new Timer(TimerDelegate, null, 0, r.Next(10000, 25000));


   UCMASampleForwardIncomingCall ucmaSampleForwardIncomingCall = new UCMASampleForwardIncomingCall() 
   ucmaSampleForwardIncomingCall.Run();

}

TimerCallBack writes the data to the database, ucmaSampleForwardIncomingCall is the "main" method of the program, all is important at this stage that after initial configuration it waits for an event. But the code above executes the timer only once... I was thinking about putting the ucmaSampleForwardIncomingCall on separate thread:

   public static void Main(string[] args)
{
   Random r = new Random();
   System.Threading.TimerCallback TimerDelegate = new System.Threading.TimerCallback(TimerCallBack);
   Timer TimerItem = new Timer(TimerDelegate, null, 0, r.Next(10000, 25000));
   Thread callThread = new Thread(new ThreadStart(ucmaSampleForwardIncomingCall.Run));
   callThread.Start();

but still the timer executes only once. I've read "How-to set timer" thread but I'm still confused here...

EDIT: using GC.keepAlive(TimerItem) solved the issue.

edit 2: or not... after few events the timer stops, probably when there was exception caught in the ucmaSampleForwardIncomingCall

edit 3: currently working with:

     public static void Main(string[] args)
    {
     Random r = new Random();
     Timer TimerItem = new Timer(TimerCallBack, null, 0, r.Next(10000, 15000));
      ucmaSampleForwardIncomingCall.Run();
     GC.KeepAlive(TimerItem);
  }

    private static void TimerCallBack(Object o)
    {.... more code.....}

But I'm not holding my hopes too high...

Community
  • 1
  • 1
Yasskier
  • 791
  • 1
  • 14
  • 36
  • 1
    The upvoted answers in that SO question all have the same bug you do. The `TimerItem` variable is not enough to prevent the Timer object from getting garbage collected. Store it in a static field or put GC.KeepAlive(TimerItem) at the end of your Main() method. – Hans Passant Dec 14 '14 at 21:43
  • Thank you, could you please put it as an answer so I can mark it? – Yasskier Dec 14 '14 at 21:59
  • Unfortunately it didn't solve the issue on the longer run: yes, it does run but after few events the timer stops anyway. :( – Yasskier Dec 14 '14 at 22:10

1 Answers1

1

I can not comment on your question because of reputation under 50 :D but I think it's better to define a field for your timer because if callback is a static field then it's root object needs to be defined in same scope. Code will be like this and I hope this will help you.

private static Timer timer = new Timer();

public static void Main(string[] args)
{
    // timer properties will be set here
    timer.Tick += timer_Tick;
    ucmaSampleForwardIncomingCall.Run();
}

private static void timer_Tick(Object o) {}
M.G.E
  • 371
  • 1
  • 10