HttpWebRequest在一台电脑上无法正常运行

5
我有一段代码,它向Google钱包发送一个HttpWebRequest请求。在我所有的机器上,这段代码都能正常工作,但是在我现在使用的这台工作电脑上却无法正常运行。这台电脑上的互联网连接没有问题(因为我正在使用它打字提出这个问题),而且我们在办公室没有代理服务器。
问题在于程序会一直挂起,甚至不会超时。它只是无动静,没有任何错误信息,最后我不得不强制关闭它。以下是代码:
    private static string GetLoginHtml()
    {
        var request = (HttpWebRequest)WebRequest.Create(LoginUrl);
        var cookieJar = new CookieContainer();

        request.Method = "POST";
        request.ContentType = "application/x-www-form-urlencoded";
        request.CookieContainer = cookieJar;
        using (var requestStream = request.GetRequestStream())
        {
            string content = "Email=" + Username + "&Passwd=" + Password;
            requestStream.Write(Encoding.UTF8.GetBytes(content), 0, Encoding.UTF8.GetBytes(content).Length);
            using (var sr = new StreamReader(request.GetResponse().GetResponseStream()))
            {
                string html = sr.ReadToEnd();
                string galxValue = ParseOutValue(html, "GALX");

                return GetLoginHtml2(galxValue, cookieJar);
            }
        }
    }

当我在Visual Studio调试器上逐步执行代码时,我知道它在遇到以下这行代码时挂起:

using (var sr = new StreamReader(request.GetResponse().GetResponseStream()))

具体来说,request.GetResponse() 部分是出现问题的。在运行 Fiddler 时,我只看到一个灰色条目,它看起来像这样:
 3     200    HTTP            Tunnel to     accounts.google.com:443            0

没有其他东西。没有响应体。有人对可能发生的事情有任何建议吗?它只在这台计算机上发生的事实告诉我,这可能不是编程问题。


@JohnSaunders - 是的。正如我在问题中所述,我使用Visual Studio调试器逐步执行代码。它挂在这一行上:using (var sr = new StreamReader(request.GetResponse().GetResponseStream())) - Icemanind
抱歉,我猜我忽略了你问题中的那一行。作为诊断,我建议你将其拆分成以下几行:using (var rsp = request.GetResponse()) using (var strm = rsp.GetResponseStream()) using (var sr = new StreamReader(strm)),每行单独放在一行上。很有意思知道其中哪一行出现了问题。 - John Saunders
@JohnSaunders - 哈哈,正如我在问题中所述,是request.GetResponse()这部分卡住了。 - Icemanind
那你是怎么确定它不是 GetResponseStream() 方法引发的问题的呢? - John Saunders
@JohnSaunders - 因为我将代码分开并将每个部分放在自己的行上。当调试器遇到 request.GetResponse() 这一行时,它就卡住了。 - Icemanind
显示剩余2条评论
1个回答

6

我终于找出了这个问题。我发布这个答案是为了帮助未来遇到类似问题的人。

现在这是我的可运行代码:

private static string GetLoginHtml()
{
    var request = (HttpWebRequest)WebRequest.Create(LoginUrl);
    var cookieJar = new CookieContainer();

    request.Method = "POST";
    request.ContentType = "application/x-www-form-urlencoded";
    request.CookieContainer = cookieJar;
    using (var requestStream = request.GetRequestStream())
    {
        string content = "Email=" + Username + "&Passwd=" + Password;
        requestStream.Write(Encoding.UTF8.GetBytes(content), 0, Encoding.UTF8.GetBytes(content).Length);
    }
    using (var sr = new StreamReader(request.GetResponse().GetResponseStream()))
    {
        string html = sr.ReadToEnd();
        string galxValue = ParseOutValue(html, "GALX");

        return GetLoginHtml2(galxValue, cookieJar);
    }
}

我的猜测是我的请求流在获取响应流之前没有被垃圾收集和关闭。我认为响应流在请求流完成写入字节之前已经被打开并读取了。真是傻.NET垃圾收集器。


2
你的猜测是正确的。流需要被刷新,因为如果没有关闭它或者手动刷新它,你不能保证什么时候(或者是否)它会刷新,这意味着(在这个情况下)你的HTTP请求实际上永远不会结束,从服务器的角度来看。添加using块可以强制刷新流,并允许在调用GetResponse()时发送一个结束HTTP请求的CRLFCRLF序列给服务器。 - dodexahedron

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