Reputation: 829
I am writing some C# 2.0 code which must do basic HTTP GETs and POSTs. I am using System.Net.HttpWebRequest to send both types of request and System.Net.HttpWebResponse to receive both. My code for GET looks like:
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(String.Format("{0}?{1}",
URLToHit,
queryString));
request.Method = "GET";
request.Timeout = 1000; // set 1 sec. timeout
request.ProtocolVersion = HttpVersion.Version11; // use HTTP 1.1
try
{
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
}
catch(WebException e)
{
// If I do anything except swallow the exception here,
// I end up in some sort of endless loop in which the same WebException
// keeps being re-thrown by the GetResponse method. The exception is always
// right (ie: in cases when I'm not connected to a network, it gives a
// timed out error, etc...), but it should not be re-thrown!
}
And my POST code is very similar.
The last line works fine when URLToHit returns a HTTP status 200, but in any other circumstance (ie: non 200 HTTP status, no network connectivity, etc...), a System.Net.WebException is thrown (which is expected, according to MSDN docs). However, my code never makes progress past that line.
When I attempt to debug this, I find that I can't step over or continue past that last line. When I try to do so, the request is re-issued and the exception re-thrown.
Any ideas on what I can do to make the request only be issued once? I've never seen anything like this happen in any exception based code, and I'm out of ideas. Nothing like this happens in any other parts of my code, just the parts that deal with System.Net functionality and constructs.
Thanks!
(Update: added try/catch around the GetRequest method)
Upvotes: 5
Views: 1352
Reputation: 43
I have the exact same problem. Here is how I produce it:
bool shouldRetry = true;
do {
try
{
Stream newStream = myHttpWebRequest.GetRequestStream();
newStream.Write(byteArray, 0, byteArray.Length);
newStream.Close();
HttpWebResponse response = (HttpWebResponse)myHttpWebRequest.GetResponse();
shouldRetry = false;
response.Close();
tries++;
status = response.StatusDescription;
}
catch (WebException e)
{
tries++;
if (tries >= 5)
{
throw e;
}
else
{
Thread.Sleep(1000);
}
}
} while (shouldRetry);
To induce the exception, I've changed my host table so the URI goes to my localhost that does not provide any proper response.
But the exception is constantly thrown! If I debug in Visual Studio, it stops at
throw e;
with an "uncaught exception" notice/box. if I press "play" to continue debugging, same row throws exception, I can not go forward in the code.
Also, it doesn't matter WHERE I throw the error. I've tried saving it and throw it after the do/while, after the function call, etc.. The exception is still thrown and is constantly there. Only way to leave is to stop debugger / exit webserver. (on localhost the process takes 100% of its CPU), when this state occur on webserver host, IIS is restarted after a while.
Aaron, did you ever solve this problem? I need that exception and I can't "swallow" it.
UPDATE: 2010-12-16
This code is in a function called send(). That function is actually called within a ThreadPool.QueueUserWorkItem like this.
ThreadPool.QueueUserWorkItem((object state) =>
{
Thread.Sleep(1);
try
{
send();
}
catch (Exception e)
{
throw e;
}
});
I'm currently trying to find out if that has something to do with the non-stop exceptions that eventually crash the server in my case. As I said.. It doesn't matter WHERE I catch the exception.
UPDATE: 2010-12-16 (part 2)
I do NOT get the never ending error if I avoid using ThreadPool.QueueUserWorkItem.
I'll continue to investigate.. But perhaps I could manage without ThreadPool.QueueUserWorkItem.
UPDATE: 2010-12-16 (part 3)
Thread.CurrentThread.Abort();
Instead of throwing error solves my issue
Upvotes: 1
Reputation: 9017
Another side note, there is a difference between these two code snippets:
catch (Exception e)
{
throw e;
}
catch (Exception e)
{
throw;
}
The first example will actually reset the stack trace in the exception to the current stack location, the second example will keep the existing stack trace. It may help you to debug your problem if you switch your code to the second example.
Upvotes: 1
Reputation: 106904
Here's some food for thought: the debugger can execute code as well. For example, when you evaluate a property (in a watch, or QuickWatch, or even just hovering the mouse over its name for the value tooltip), the debugger will execute the underlying code. And hit any breakpoints it meets during this. Perhaps this is the cause? What are the callstacks in the subsequent exceptions? Does this also happen without a debugger?
Upvotes: 0
Reputation: 23721
I've seen similar issues to this one, and usually it's only in the debugger itself that the line throwing the exception is re-run, but this only happens when the exception is ultimately uncaught.
You say that it only exhibits this behaviour when you re-throw in the catch block. Since you're re-throwing the exception, where is that exception eventually getting caught and dealt with (i.e. by a catch handler that doesn't end with a (re)throw)?
If the answer is "nowhere", then that's your problem - under the debugger you're likely to see this re-running of the exception-throwing line, and when run normally, the application will ordinarily crash due to an uncaught exception.
Upvotes: 1
Reputation: 9863
There's no such thing as a "non-stop" exception in C#. To control what happens during an exception, you use a try-catch block.
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(String.Format("{0}?{1}",
URLToHit,
queryString));
request.Method = "GET";
request.Timeout = 1000; // set 1 sec. timeout
request.ProtocolVersion = HttpVersion.Version11; // use HTTP 1.1
try
{
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
// Code here runs if GetResponse() was successful.
}
catch (WebException ex)
{
// Code here runs if GetResponse() failed.
}
// Code here is always run unless another exception is thrown.
The reason there are no "non-stop exceptions" is because, if there is an exception, your code can't possibly do what you intended. For example, what would you expect the "response" variable to contain? What would you do with it? The try-catch block gives you full control over this.
Upvotes: 1