How to end a HttpWebRequest connection in C #? This does not work even when setting a timeout or readwritetimeout

I want to complete httpwebrequest when it takes too much time to connect. Here are just the simaple code I wrote:

HttpWebRequest request = (HttpWebRequest)WebRequest.Create(URL); request.Timeout = 5000; request.ReadWriteTimeout = 5000; request.Proxy = new WebProxy("http://" + proxyUsed + "/", true); request.UserAgent = "Mozilla/4.0 (compatible; MSIE 6.01; Windows NT 5.0)"; using (WebResponse myResponse = request.GetResponse()) { using (Stream s = myResponse.GetResponseStream()) { s.ReadTimeout = 5000; s.WriteTimeout = 5000; using (StreamReader sr = new StreamReader(s, System.Text.Encoding.UTF8)) { result = sr.ReadToEnd(); httpLink = myResponse.ResponseUri.AbsoluteUri; sr.Close(); } s.Close(); } myResponse.Close(); } 

However, sometimes it takes about 15 minutes to get a response to the connection. The situation after 15 minutes I can still get a response, but not the full source code of the URL. I assume that the connection is too slow, that the URL will respond to some data within a timeout, just say, for example, get 1 byte in 5 seconds, so timoue does not expire, but it is very long. How can I end the connection? Thanks:)

+7
source share
3 answers

You may find that the timeout does work, but the thread freezes when you try to close the stream. I do not know why this happens, but sometimes it happens. I never used ReadToEnd , but I used this when using Read .

I fixed the problem by calling Abort on request before I close the stream. It is a little kluge, but it is effective. The abbreviated code below shows the technique.

 HttpWebResponse response = null; StreamReader sr = null; try { response = (HttpWebResponse)request.GetResponse(...); Stream s = response.GetResponseStream(); sr = new StreamReader(s, Encoding.UTF8); // do your reading here } finally { request.Abort(); // !! Yes, abort the request if (sr != null) sr.Dispose(); if (response != null) response.Close(); } 

I found that ReadTimeout and ReadWriteTimeout work as expected. That is, when the reading time ends, the execution really goes into the finally block. And if request.Abort does not exist, the sr.Dispose call will hang.

+5
source

Cancel the stream reading and abort if the total time is too long.

 HttpWebRequest request = (HttpWebRequest)WebRequest.Create(URL); request.Timeout = 5000; request.ReadWriteTimeout = 5000; request.Proxy = new WebProxy("http://" + proxyUsed + "/", true); request.UserAgent = "Mozilla/4.0 (compatible; MSIE 6.01; Windows NT 5.0)";//ahem! :) DateTime giveUp = DateTime.UtcNow.AddSeconds(5); using (WebResponse myResponse = request.GetResponse()) { httpLink = myResponse.ResponseUri.AbsoluteUri; using (Stream s = myResponse.GetResponseStream()) { s.ReadTimeout = 5000; s.WriteTimeout = 5000; char[] buffer = new char[4096]; StringBuilder sb = new StringBuilder() using (StreamReader sr = new StreamReader(s, System.Text.Encoding.UTF8)) { for(int read = sr.Read(buffer, 0, 4096); read != 0; read = sr.Read(buffer, 0, 4096)) { if(DateTime.UtcNow > giveUp) throw new TimeoutException(); sb.Append(buffer, 0, read); } result = sb.ToString(); } } } 
+2
source

Remember to also close the connection in the event of an exception. In this case, the WebResponse object is in a WebException:

 try { using (WebResponse myResponse = request.GetResponse()) // do stuff } catch (WebException webEx) { webEx.Response.Close(); } 
0
source

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


All Articles