Keep talking to the server when the Internet is down

So, my application exchanges requests and responses with the server (no problem) until the Internet connection dies for a couple of seconds, and then returns. Then this code:

response = (HttpWebResponse)request.GetResponse();

will throw an exception with a status like ReceiveFailure , ConnectFailure , KeepAliveFailure , etc.

Now it is very important that if the Internet connection returns, I can continue to communicate with the server, otherwise I will have to start from the very beginning, and this will take a lot of time.

How could you resume this conversation when the Internet returns?

At the moment, I continue to test the possibility of communication with the server until this is possible (at least theoretically). My code attempt looks like this:

 try { response = (HttpWebResponse)request.GetResponse(); } catch (WebException ex) { // We have a problem receiving stuff from the server. // We'll keep on trying for a while if (ex.Status == WebExceptionStatus.ReceiveFailure || ex.Status == WebExceptionStatus.ConnectFailure || ex.Status == WebExceptionStatus.KeepAliveFailure) { bool stillNoInternet = true; // keep trying to talk to the server while (stillNoInternet) { try { response = (HttpWebResponse)request.GetResponse(); stillNoInternet = false; } catch { stillNoInternet = true; } } } } 

However, the problem is that the second try-catch statement continues to throw an exception, even when the Internet has returned.

What am I doing wrong? Is there any other way to do this?

Thanks!

+6
source share
3 answers

You must recreate the request each time, and you must execute the retries in a loop with the wait between each attempt. The latency should gradually increase with each failure.

eg.

 ExecuteWithRetry (delegate { // retry the whole connection attempt each time HttpWebRequest request = ...; response = request.GetResponse(); ... }); private void ExecuteWithRetry (Action action) { // Use a maximum count, we don't want to loop forever // Alternativly, you could use a time based limit (eg, try for up to 30 minutes) const int maxRetries = 5; bool done = false; int attempts = 0; while (!done) { attempts++; try { action (); done = true; } catch (WebException ex) { if (!IsRetryable (ex)) { throw; } if (attempts >= maxRetries) { throw; } // Back-off and retry a bit later, don't just repeatedly hammer the connection Thread.Sleep (SleepTime (attempts)); } } } private int SleepTime (int retryCount) { // I just made these times up, chose correct values depending on your needs. // Progressivly increase the wait time as the number of attempts increase. switch (retryCount) { case 0: return 0; case 1: return 1000; case 2: return 5000; case 3: return 10000; default: return 30000; } } private bool IsRetryable (WebException ex) { return ex.Status == WebExceptionStatus.ReceiveFailure || ex.Status == WebExceptionStatus.ConnectFailure || ex.Status == WebExceptionStatus.KeepAliveFailure; } 
+15
source

I think you are trying to do this:

 HttpWebResponse RetryGetResponse(HttpWebRequest request) { while (true) { try { return (HttpWebResponse)request.GetResponse(); } catch (WebException ex) { if (ex.Status != WebExceptionStatus.ReceiveFailure && ex.Status != WebExceptionStatus.ConnectFailure && ex.Status != WebExceptionStatus.KeepAliveFailure) { throw; } } } } 

If you want to repeat something when you make a mistake, instead of thinking of it as something you want to do when something fails, think of it instead as a cycle until you succeed. (or a failure that you do not want to repeat). The above will continue to retry until a response is returned or another exception is sent.

It would be nice to enter a maximum retry limit of some kind (for example, stop retrying after 1 hour).

+1
source

If it still does this when you return the connection, then I assume that it returns the same result again.

You might want to try re-creating the query again every time, except that I don’t see a lot of the wrong code or logic. In addition to blocking this thread forever. But then it can be good if it is a workflow in itself.

0
source

Source: https://habr.com/ru/post/894379/


All Articles