简体   繁体   中英

When creating a new timer, what will happen to the old?

I have inherit some old code and it looks to me that there is an problem with some part(s) of it.

The program uses TCP/IP to communicate with another program and the protocol is simple. Send a command Telegram and wait for a response telegram.

Here is the part that's I think is problematic.

public System.Timers.Timer retransmitTimer;

public TelegramBase SendAndWait(TelegramBase telegram)
{
    CurrentTelegram = telegram;

    retransmitTimer = new Timer(RetransmitInterval);
    retransmitTimer.Elapsed += retransmitTimer_Elapsed;

    //Send telegram
    Send(telegram);

    //Start timer
    retransmitTimer.Start();

    //Wait for response
    var response = WaitForResponse(telegram as StandardTelegram);

    //stop timer
    retransmitTimer.Stop();

    return response;
}

The method SendAndWait is called every time a command telegram is sent.

My issue is the creation of the timer

    retransmitTimer = new Timer(RetransmitInterval);
    retransmitTimer.Elapsed += retransmitTimer_Elapsed;

This will create a new timer, but the current one is never disposed so it will keep on running? Best scenario it will be stopped.

What is better?

  1. Move the creation of the timer to a method that is only called once?
  2. Dispose of the current timer and then create a new one in SendAndWait?

I would wrap the timer in a using statement:

public TelegramBase SendAndWait(TelegramBase telegram)
{
    CurrentTelegram = telegram;

    using (Timer retransmitTimer = new Timer(RetransmitInterval))
    {
        retransmitTimer.Elapsed += retransmitTimer_Elapsed;

        //Send telegram
        Send(telegram);

        //Start timer
        retransmitTimer.Start();

        //Wait for response
        var response = WaitForResponse(telegram as StandardTelegram);

        //stop timer
        retransmitTimer.Stop();
    }

    return response;
}

From the description of System.Timers.Timer , it seems to be quite heavy object, so initializing it with every message may have pretty large overhead. If you feel like you are struggling with performance, this would be the place to look. You could do some microbenchmarks to time the execution time of the timer constructor compared to the rest of the method.

In your current implementation, the retransmitTimer should be local variable contained in a using statement, as you can see in the other answer.

If you decide to use one timer per class, then instead of calling the Timer constructor with RetransmittInterval , you can use the Interval property of existing Timer instance to set the interval. With this implementation you should implement IDisposable on the class that contains the SendAndWait method, and dispose the timer in the Dispose method of your class.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM