retry logic?

raysefo

Well-known member
Joined
Feb 22, 2019
Messages
155
Programming Experience
10+
Are there any other ways to retry logic?
C#:
bool redo = false;
const int maxRetries = 3;
int retries = 0;

 do
{

    try
    {

       HttpWebRequest req = (HttpWebRequest) WebRequest.Create("http://www.google.com");
       req.Timeout = 10000;

       HttpWebResponse res = (HttpWebResponse) req.GetResponse();

    }catch (TimeoutException e)
    {

       Console.WriteLine(e.Message);
       redo = true;
       ++retries;

    }
 }while (redo && retries < maxRetries) ;
 

Skydiver

Well-known member
Joined
Apr 6, 2019
Messages
365
Location
Virginia Beach, VA
Programming Experience
10+
If you move the code into a method and follow the Single Responsibility Principle, then yes, because you can just return out of the method.
 

Sheepings

Senior Programmer
Joined
Sep 5, 2018
Messages
345
Location
UK
Programming Experience
10+
That code is horrible. What if the server is non responsive for a while. Wouldn't it be better to have a timer which would chech periodically, thus allowing the executed code more time before retrying?

Ask a mod to split your topic at post 17 now there are replies on it...
 

Skydiver

Well-known member
Joined
Apr 6, 2019
Messages
365
Location
Virginia Beach, VA
Programming Experience
10+
Or instead of polling with a timer, use the actual built in asynchronous methods: HttpWebRequest.BeginGetResponse(). That should schedule an operation that will fire up a thread pool to call the callback method when the connection succeeds or fails without typing up the current running thread.
 

Skydiver

Well-known member
Joined
Apr 6, 2019
Messages
365
Location
Virginia Beach, VA
Programming Experience
10+
While you investigate that, here's the general pattern in pseudo-code to structuring retry logic using a method:
Code:
bool TryDoAction(Action doSomething, int maxTries)
{
    while (maxTries-- > 0)
    {
        try
        {
            doSomething();
            return true;
        }
        catch(SomeExpectedException ex)
        {
            // log the exception and try count
        }

        // optionally put in some delay or back off heuristic here before trying again
    }
    return false;
}
Be sure to only catch exceptions that you expect and know how to handle. You'll want unexpected exceptions to bubble up immediately.
 

Sheepings

Senior Programmer
Joined
Sep 5, 2018
Messages
345
Location
UK
Programming Experience
10+
I don't see anything wrong with a timed response. As an aside, I thought this might be worth mentioning, as most devs overlook this. But, if you think you may have a dodgy connection to or from a server. You can use the using directive : using System.Net.NetworkInformation; and use the ping method in c# to check whichever server for a response. If the server(s) respond, while a request will not, you know you've got problems with your code, and not your network or server. With a few lines, you can test it like so :
C#:
            try
            {
                string domain = "csharpforums.net";
                using (Ping hitme = new Ping())
                {
                    var reply = hitme.Send(domain); bool responsive = reply.Status == IPStatus.Success; Console.WriteLine($"Response from {domain} is :: {reply.Status}");
                }
            }
            catch
            {
            }
If you run it in a function, ensure you add PingException to the catch and then have that return false. If you're running it inline with other code, ie web request/response, its fine as it and safe to ignore errors. There are some other nice little bits to plug and play with in that using directive for testing connections etc.
 

Skydiver

Well-known member
Joined
Apr 6, 2019
Messages
365
Location
Virginia Beach, VA
Programming Experience
10+
Every approach has their pros and cons:
Timers are limited resources, be they Windows timers or system timers. If using Windows timers, you need to make sure you have a message pump running, and you need to keep a mental model of the cooperative multitasking that is actually happening -- a Windows timer doesn't preempt any other code currently running on the UI thread. If using a system timer, then you'll need to be wary of cross thread issues.

On the other hand, using Sleep() won't cost much, except for tying up the current thread until the sleep time elapses. This would suck big time if the thread happens to be the UI thread, or an ASP.NET thread used to handle web requests.

Using async, await, coupled with Task.Delay() will free up the current thread to do other work, but introduces the overhead of the compiler generated code to make async and await to work. Again, just like with the Windows timer, there is an aspect of keeping a mental model of the cooperative-multitasking that is actually happening to prevent accidentally deadlocking yourself.
 
Top Bottom