Retrying WebRequest.GetResponse()

  • Thread starter Thread starter Scott Wegner
  • Start date Start date
S

Scott Wegner

Hi All,

Just a quick question. I'm performing a simple web query with a timeout
using the WebRequest.GetResponse() method. I was wondering if it is safe to
use the same WebRequest to query after it has timed out once. In the remarks
for the HttpWebRequest.GetResponse() method
(http://msdn.microsoft.com/en-us/library/system.net.httpwebrequest.getresponse.aspx):

Multiple calls to GetResponse return the same response object; the request
is not reissued.

However, when the a request times out, an exception is thrown. I just want
to make sure I can use the same WebRequest to retry the query, and that the
exception will not be cached and returned promptly.

My code looks something like this:

WebRequest request = WebRequest.Create(MY_URL);
request.Timeout = MY_TIMEOUT;
WebResponse response = null;
int numTries = 0;

while ((response == null) && (numTries < RETRY_LIMIT))
try { response = request.GetResponse(); }
catch(WebException ex) { numTries++; }


Thanks in advance.
 
Scott said:
Just a quick question. I'm performing a simple web query with a timeout
using the WebRequest.GetResponse() method. I was wondering if it is safe to
use the same WebRequest to query after it has timed out once. In the remarks
for the HttpWebRequest.GetResponse() method
(http://msdn.microsoft.com/en-us/library/system.net.httpwebrequest.getresponse.aspx):

Multiple calls to GetResponse return the same response object; the request
is not reissued.

However, when the a request times out, an exception is thrown. I just want
to make sure I can use the same WebRequest to retry the query, and that the
exception will not be cached and returned promptly.
Questions like these always make me wonder "why don't you just try it?" If
it fails just once, you know you can't use it.

I tried it, and I also looked at the implementation, and these two combined
allow me to state with some confidence that this will always fail. One
WebRequest can only ever issue one request. If you want to issue another,
you have to create a new WebRequest object.
 
Hi Jeroen,
Jeroen Mostert said:
Questions like these always make me wonder "why don't you just try it?" If
it fails just once, you know you can't use it.

I wasn't able to try it myself easily because I couldn't think of a way to
set up an environment where the first call might fail, but subsequent calls
might succeed. The case I'm trying to code for is when a request might
timeout (after say, 2 seconds) due to server latency. But perhaps the server
would respond within the time limit on a subsequent response.
I tried it, and I also looked at the implementation, and these two combined
allow me to state with some confidence that this will always fail. One
WebRequest can only ever issue one request. If you want to issue another,
you have to create a new WebRequest object.

I'm not sure this answers my question. Referring to my above comment, I'm
trying to code for the case when the request fails due to a timeout. In this
case, as WebException is raised before the WebResponse is ever returned. You
mention that "One WebRequest can only ever issue one request." From the
documentation, though, it sounds like this should be augmented that "One
WebRequest can only ever issue one *response*". A WebResponse is never
actually returned in this case, so is it valid to try again using the same
WebRequest?

Scott
 
Scott said:
Hi Jeroen,


I wasn't able to try it myself easily because I couldn't think of a way to
set up an environment where the first call might fail, but subsequent calls
might succeed.

I used a port listener (netcat for Windows) with a test program that did a
request, waited for me to press Enter, then called .GetResponse() on the
same request. I forced the first request to fail by not listening, then
started my listener, then hit Enter. No request, just the same exception. (I
also verified that it worked when I did hook up the listener, of course.)

This was after I gleaned the implementation to verify that it never actually
retried requests.
The case I'm trying to code for is when a request might timeout (after
say, 2 seconds) due to server latency. But perhaps the server would
respond within the time limit on a subsequent response.
I assume you mean "a subsequent request"?

Reissuing the request is certainly possible, you just have to create a new
WebRequest object with the same data.

You can't code for the case where the server responds after all, when your
side has stopped listening. In this case, the response is lost. With any
luck, the server will see that the connection got reset and its response
wasn't received, but it might already have performed your request. You can't
really guard against this without putting some way of identifying requests
in your protocol logic, or adding transactional logic.
I'm not sure this answers my question. Referring to my above comment, I'm
trying to code for the case when the request fails due to a timeout.

It's irrelevant if the request fails or succeeds. After you've tried it
once, you'll get back the same result, whether that's a WebResponse object
or an exception. (Internally, it *does* have a response object, but it has
an associated error, so it's not returned -- instead the associated error is
raised).

To put it another way, after you've called .GetResponse() and ascertained
what's the case, the WebRequest object is useless, "spent". It can't do
anything more for you.
In this case, as WebException is raised before the WebResponse is ever
returned. You mention that "One WebRequest can only ever issue one
request." From the documentation, though, it sounds like this should be
augmented that "One WebRequest can only ever issue one *response*".

It depends on how you define "request". If you consider all requests with
the same content "the same request", then "retrying" that request is
meaningful. In the case of WebRequest, though, you should consider one
particular request issued at one particular moment in time "one request". In
this sense it's impossible to try the same request twice. Like that
philosophical riddle about how you can't cross the same river twice.
A WebResponse is never actually returned in this case, so is it valid to
try again using the same WebRequest?
Define "valid". It doesn't raise an InvalidOperationException. It just
doesn't retry the request either. One request, one outcome.
 
Jeroen Mostert said:
I used a port listener (netcat for Windows) with a test program that did a
request, waited for me to press Enter, then called .GetResponse() on the
same request. I forced the first request to fail by not listening, then
started my listener, then hit Enter. No request, just the same exception. (I
also verified that it worked when I did hook up the listener, of course.)

This was after I gleaned the implementation to verify that it never actually
retried requests.

I assume you mean "a subsequent request"?

Reissuing the request is certainly possible, you just have to create a new
WebRequest object with the same data.

You can't code for the case where the server responds after all, when your
side has stopped listening. In this case, the response is lost. With any
luck, the server will see that the connection got reset and its response
wasn't received, but it might already have performed your request. You can't
really guard against this without putting some way of identifying requests
in your protocol logic, or adding transactional logic.


It's irrelevant if the request fails or succeeds. After you've tried it
once, you'll get back the same result, whether that's a WebResponse object
or an exception. (Internally, it *does* have a response object, but it has
an associated error, so it's not returned -- instead the associated error is
raised).

To put it another way, after you've called .GetResponse() and ascertained
what's the case, the WebRequest object is useless, "spent". It can't do
anything more for you.


It depends on how you define "request". If you consider all requests with
the same content "the same request", then "retrying" that request is
meaningful. In the case of WebRequest, though, you should consider one
particular request issued at one particular moment in time "one request". In
this sense it's impossible to try the same request twice. Like that
philosophical riddle about how you can't cross the same river twice.

Define "valid". It doesn't raise an InvalidOperationException. It just
doesn't retry the request either. One request, one outcome.

Ok, I guess I believe you now. :) Thanks for testing it out and helping me
through understanding. Your last sentence here sums it up best-- "One
request. one outcome."

Scott
 
Back
Top