如何在C#中终止HttpWebRequest连接?即使设置超时或readwritetimeout也不起作用

发布于 2024-12-10 19:35:52 字数 1235 浏览 10 评论 0原文

我想在连接时间过长时终止 httpwebrequest。 这里只是我写的一个简单代码:

            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();
            }

但是,有时连接需要大约 15 分钟才能得到响应。 情况是 15 分钟后我仍然可以得到响应,但不能得到 URL 的完整源代码。 我猜想连接太慢了,URL 在超时时间内回复了一些数据,比如在 5 秒内接收到 1 个字节,所以它不会过期,但它很长。 我怎样才能终止连接? 谢谢:)

I want to terminate a httpwebrequest when it takes too long time in connection.
Here is just a simaple code that 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 the connection will take a about 15minutes to get the response.
The situation is after 15minutes I still can get the response but not the full source code of the URL.
I guess that the connection is too slow that the URL response me a bit data within the timeout, just say for example receive 1byte in 5seconds, so it doesn't expire the timoue but it's very long.
How can I terminate the connection?
Thanks:)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

咿呀咿呀哟 2024-12-17 19:35:52

您可能会发现超时实际上起作用了,但在尝试关闭流时线程挂起。我不知道为什么会这样,但有时确实会这样。我从未使用过 ReadToEnd,但在使用 Read 时遇到过这种情况。

在关闭流之前,我通过对请求调用 Abort 解决了该问题。虽然有点麻烦,但很有效。下面的缩写代码展示了该技术。

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();
}

我发现 ReadTimeoutReadWriteTimeout 按预期工作。也就是说,当读取超时时,执行确实会转到finally 块。如果 request.Abort 不存在,则对 sr.Dispose 的调用将挂起。

You might find that the timeout is actually working, but the thread hangs when trying to close the stream. I don't know why it happens, but sometimes it does. I've never used ReadToEnd, but I've run across this when using Read.

I fixed the problem by calling Abort on the request, before I close the stream. It's a bit of a kluge, but it's 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();
}

What I've found is that the ReadTimeout and ReadWriteTimeout work as expected. That is, when the read times out, execution really does go to the finally block. And if the request.Abort isn't there, the call to sr.Dispose will hang.

够钟 2024-12-17 19:35:52

分解流读取,如果总时间太长则中止。

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();
        }
    }
}

Break down the stream reading, and abort if the total time has been 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();
        }
    }
}
久夏青 2024-12-17 19:35:52

确保在出现异常时也关闭连接。在这种情况下,WebResponse 对象位于 WebException 上:

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

Make sure to also close the connection on exception. In that case the WebResponse object is on the WebException:

try
{
    using (WebResponse myResponse = request.GetResponse())
      // do stuff
}
catch (WebException webEx)
{
    webEx.Response.Close();
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文