HttpWebRequest 突然停止工作,几个请求后没有收到响应

7
我正在使用一个WPF .net 4.0应用程序。我有一个搜索栏。对于每个搜索令牌,我需要对8个不同的URL进行8个http请求以获取搜索结果。一旦用户停止在搜索栏中输入,我会在400毫秒后向服务器发送8个请求。当搜索6到7个搜索令牌时,结果非常好。但是,在此之后,HttpWebRequest突然无声地停止工作。没有抛出异常,也没有收到响应。我正在使用Windows 7,我已经禁用了防火墙。我不知道后续的http请求在哪里丢失了。
有人能告诉我如何解决这个问题吗?
以下是我的HttpWebRequest调用代码。
public static void SendReq(string url)
{
    // Create a new HttpWebRequest object.
    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);

    request.ContentType = "application/x-www-form-urlencoded";
    request.Proxy = new WebProxy("192.168.1.1", 8000);

    // Set the Method property to 'POST' to post data to the URI.
    request.Method = "POST";

    // start the asynchronous operation
    request.BeginGetRequestStream(new AsyncCallback(GetRequestStreamCallback), request);

}

private static void GetRequestStreamCallback(IAsyncResult asynchronousResult)
{
    HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState;

    // End the operation
    Stream postStream = request.EndGetRequestStream(asynchronousResult);

    string postData = this.PostData;

    // Convert the string into a byte array. 
    byte[] byteArray = Encoding.UTF8.GetBytes(postData);

    // Write to the request stream.
    postStream.Write(byteArray, 0, byteArray.Length);
    postStream.Close();

    // Start the asynchronous operation to get the response
    request.BeginGetResponse(new AsyncCallback(GetResponseCallback), request);
}

private static void GetResponseCallback(IAsyncResult asynchronousResult)
{
    HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState;

    // End the operation
    using(HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(asynchronousResult))
    {
        using(Stream streamResponse = response.GetResponseStream())
        {
             using(StreamReader streamRead = new StreamReader(streamResponse))
             {
                 string responseString = streamRead.ReadToEnd();
                 Debug.WriteLine(responseString);
             }
        }
    }
}

1
你有多确定其他请求没有抛出异常?你的“Close”调用不在“using”语句中,这意味着如果有异常,你会留下响应连接,这可能导致后续请求死锁... - Jon Skeet
1
GetRequestStreamCallback 中读取控制台输入是什么意思?难道在发送请求之前真的需要输入一些内容吗? - Clemens
@Clemens,是的,我也只发布了很少量的数据。我有一些需要发送到服务器的帖子参数。我有一个包装器类来提供postData给这个代码。 - Somnath
GetRequestStreamCallback 中的控制台输入不会阻塞,对吗? - Clemens
@JonSkeet,确实测试同步版本是个好主意。我很快会尝试。 - Somnath
显示剩余5条评论
4个回答

6
我觉得我来晚了,但我仍然想回答你的问题,也许对其他人有所帮助。默认情况下,您发起的HTTP请求都是HTTP 1.1请求。并且HTTP 1.1请求默认具有“保持活动”连接。因此,当您向同一服务器发出太多请求时,.net框架只会发出x个请求。您应该通过“response.Close()”关闭所有响应。您还可以指定可以同时发出多少个请求。
ServicePointManager.DefaultConnectionLimit = 20;

请注意,在您进行第一次请求之前,您必须设置DefaultConnectionLimit。您可以在MSDN上找到更多信息。

2
我能看到的是,在GetRequestStreamCallback中,你应该替换
postStream.Write(byteArray, 0, postData.Length);

by

postStream.Write(byteArray, 0, byteArray.Length);

由于这些长度不一定相等。


谢谢Clemens,你说得对。刚才我已经在我的代码中做了更改。即使它没有解决HttpWebRequest静默失败的问题。 - Somnath

0

@Somnath 我不确定你是否找到了这个答案,但如果其他人遇到了与Somnath和我遇到的相同问题,他们可能会偶然发现这篇文章。

我们都尽力保持内存清洁和清晰,但是对于流,如果我们在关闭之前确保刷新流,就可以避免保存未解释的问题。

替换此内容:

postStream.Write(byteArray, 0, byteArray.Length);
postStream.Close();

使用这个:

postStream.Write(byteArray, 0, byteArray.Length);
postStream.Flush();
postStream.Close();

嗨Jdunn,我刚刚测试了你的建议,但失败了。我清空并关闭了所有流。所以我的代码中没有内存泄漏。仍然没有运气。请注意,当我继续在搜索框中输入时,在一些请求返回响应之前,我会发送太多的请求。我只是忽略以前的响应。现在我猜我需要做一些关于请求取消的事情。你有什么想法?有什么猜测吗..! - Somnath

-1

我按照大家提供的所有建议,但仍无法阻止HTTP请求的静默失败。但我找到了一个解决方法。直到现在,我自己也没有得出最终结论。

但是我的解决方法目前运行良好,没有任何故障。

SendReq(string url)函数中,我添加了以下代码行

System.Net.ServicePointManager.DefaultConnectionLimit = 100; // Just selected a random number for testing greater than 2
System.Net.ServicePointManager.SetTcpKeepAlive(true, 30, 30); // 30 is based on my server i'm hitting
System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3;

request.KeepAlive = true;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接