I'm writing an application that simplifies some web site interfaces I use at work, and one of them in particular is causing problems. It uses a persistent connection to keep you logged in. I have a relatively short timeout set on the http request since normally the website is very fast, but it is known for its bad days as well. I'd like to keep the time out low because I don't want people using the program to have to sit there forever waiting for it to do nothing.
The problem is, from what I can tell, when my program produces a time out exception, the server does not know to close the connection with my client. After two time outs, the program more or less becomes hosed, and will do nothing but time out on that web site until it's restarted or sometimes even restarting the computer. I've looked everywhere (although I'll admit I'm not very familiar with web requests so I'm probably searching the wrong things) and am having very little luck finding anything helpful on this. I need to be able to somehow tell the server that I don't want that request anymore so it'll free up a spot to avoid permanent time outs.
The few things I've known/found to try and closing or disposing the read/request streams and and aborting or closing the request and response. I've even tried setting KeepAlive to false, and that did not work. I've tried putting these in the try/catch and just for kicks in a finally too. I have also tried starting another thread, that if allowed to run long enough, will close all the streams/connections/blah and abort the requesting thread (thread where the function below runs) a little before the 10/30 second time out would happen. This also did not work, I suspect, because the requesting thread was "locked up" trying to get the request. It couldn't be aborted until it unlocked when it hit its timeout, if that would even make a difference for this.
I've included code just for completion, though really I think this is more of a problem of knowing some command to send to the server (at least I hope it's that easy) opposed to a C# issue.
The problem is, from what I can tell, when my program produces a time out exception, the server does not know to close the connection with my client. After two time outs, the program more or less becomes hosed, and will do nothing but time out on that web site until it's restarted or sometimes even restarting the computer. I've looked everywhere (although I'll admit I'm not very familiar with web requests so I'm probably searching the wrong things) and am having very little luck finding anything helpful on this. I need to be able to somehow tell the server that I don't want that request anymore so it'll free up a spot to avoid permanent time outs.
The few things I've known/found to try and closing or disposing the read/request streams and and aborting or closing the request and response. I've even tried setting KeepAlive to false, and that did not work. I've tried putting these in the try/catch and just for kicks in a finally too. I have also tried starting another thread, that if allowed to run long enough, will close all the streams/connections/blah and abort the requesting thread (thread where the function below runs) a little before the 10/30 second time out would happen. This also did not work, I suspect, because the requesting thread was "locked up" trying to get the request. It couldn't be aborted until it unlocked when it hit its timeout, if that would even make a difference for this.
I've included code just for completion, though really I think this is more of a problem of knowing some command to send to the server (at least I hope it's that easy) opposed to a C# issue.
HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(destination);
webRequest.Method = method;
webRequest.Accept = "*/*";
webRequest.AllowAutoRedirect = false;
webRequest.UserAgent = "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.12) Gecko/20080201 Firefox/2.0.0.12";
webRequest.CookieContainer = new CookieContainer();
webRequest.ContentLength = requestBytes.Length;
webRequest.ContentType = "application/x-www-form-urlencoded";
webRequest.PreAuthenticate = true;
webRequest.Referer = refer;
//webRequest.KeepAlive = false;
if (source == ThreadSource.WebCT || source == ThreadSource.Directory || source == ThreadSource.DLS || source == ThreadSource.VistaKeepAlive)
webRequest.Timeout = 10000;
if (source == ThreadSource.Vista)
webRequest.Timeout = 30000;
webRequest.Credentials = credentials;
webRequest.CookieContainer.Add(cookies.GetCookies(destination));
Stream reqStream = null;
StreamReader stream = null;
HttpWebResponse webResponse = null;
try
{
if (method == "post")
{
reqStream = webRequest.GetRequestStream();
reqStream.Write(requestBytes, 0, requestBytes.Length);
reqStream.Close();
}
webResponse = (HttpWebResponse)webRequest.GetResponse();
if (webRequest.HaveResponse)
{
foreach (Cookie retCookie in webResponse.Cookies)
{
bool cookieFound = false;
foreach (Cookie oldCookie in cookies.GetCookies(destination))
{
if (retCookie.Name.Equals(oldCookie.Name))
{
oldCookie.Value = retCookie.Value;
cookieFound = true;
}
}
if (!cookieFound)
cookies.Add(retCookie);
}
if ((webResponse.StatusCode == HttpStatusCode.Found) || (webResponse.StatusCode == HttpStatusCode.Redirect) || (webResponse.StatusCode == HttpStatusCode.Moved) || (webResponse.StatusCode == HttpStatusCode.MovedPermanently))
{
WebHeaderCollection headers = webResponse.Headers;
return SendRequestTo(method, requestBytes, new Uri(headers["location"]), refer, credentials, source);
}
stream = new StreamReader(webResponse.GetResponseStream());
String responseString = stream.ReadToEnd();
stream.Close();
return responseString;
}
}
catch (WebException e)
{
throw new Exception("Exception occured while sending request.", e);
}
throw new Exception("No response received from host.");
