Search code examples
c#timer

Execute method every 15 seconds until it works


I want a methode to check every 15 seconds if a specific device is connected/the driver for it used.

So something like:

Every 15 seconds 
{
if (Device is connected)
  {
   do sth.;
   exit loop;
  }      
}

So far I was able to create a Timer that seems to work:

{
System.Timers.Timer timer = new System.Timers.Timer();
timer.Interval = 15000;
timer.Elapsed += CheckConnection;
timer.Start();
}

Unfortunatly I have no real clue how to exit/abort the timer once my CheckConnection Method is true/find the device connected.


Solution

  • Here is a sample application which shows how you can use Polly's Retry policy to achieve the desired behaviour.

    Let's suppose your Device class looks like this:

    public class Device
    {
        private int ConnectionAttempts = 0;
        private const int WhenShouldConnectionSucceed = 7;
    
        public bool CheckConnection() => ConnectionAttempts == WhenShouldConnectionSucceed;
    
        public void Connect() => ConnectionAttempts++;
    }
    
    • It increases ConnectionAttempts each time when the Connect method has been called.
    • When the attempts counter equals with a predefined value then the CheckConnection will return true (this simulates the successful connection) otherwise false.

    The retry policy setup looks like this:

    var retry = Policy<Device>.HandleResult(result => !result.CheckConnection())
        .WaitAndRetryForever(_ => TimeSpan.FromSeconds(15),
            onRetry: (result, duration) => Console.WriteLine("Retry has been initiated"));
        
    var device = new Device();
    retry.Execute(() =>
    {
        device.Connect();
        return device;
    });
    
    
    • Until a given device is not connected (!result.CheckConnection()) it will retry for ever (WaitAndRetryForever) the Connect method.
    • Between each retry attempt it waits 15 seconds (TimeSpan.FromSeconds(15)).
    • The onRetry delegate is used here only for demonstration purposes. onRetry is optional.

    So, if I have the following simple console app:

    class Program
    {
        static void Main(string[] args)
        {
            var retry = Policy<Device>.HandleResult(result => !result.CheckConnection())
                .WaitAndRetryForever(_ => TimeSpan.FromSeconds(15),
                    onRetry: (result, duration) => Console.WriteLine("Retry has been initiated"));
    
            var device = new Device();
            retry.Execute(() =>
            {
                device.Connect();
                return device;
            });
            Console.WriteLine("Device has been connected");
        }
    }
    

    then it will print the following lines to the output:

    Retry has been initiated
    Retry has been initiated
    Retry has been initiated
    Retry has been initiated
    Retry has been initiated
    Retry has been initiated
    Device has been connected