web-dev-qa-db-ja.com

HttpWebRequest.GetResponse()は、2回目に呼び出されたときにハングします

HttpWebRequestを使用して、HTTP経由で一連のファイルをフェッチしようとしています。最初のリクエストは正常に処理されますが、同じコードを介した2回目は、GetResponse()がハングしてタイムアウトします。 WireSharkは、2番目のリクエストに対してHTTPトラフィックが送信されていないことを示しているため、APIの問題であるように見えます。

調査の結果、content-lengthの指定に関係していることがわかりました。これを省略した場合、コードは正常に機能します。

私のコードは:

HttpWebRequest  httpWebRequest = ConfigureRequest();

using (WebResponse webResponse = httpWebRequest.GetResponse())
    // On the second iteration we never get beyond this line
{
    HttpWebResponse httpWebResponse = webResponse as HttpWebResponse;

    using (Stream webResponseStream = httpWebResponse.GetResponseStream())
    {
        if (webResponseStream != null)
        {
            // Read the stream
        }
    }

    statusCode = httpWebResponse.StatusCode;
    httpWebResponse.Close();
}

症状は この質問この質問 に非常に似ているように見えますが、どちらの場合も、私がすでに行っているWebResponseを破棄することをお勧めします。

EditGregoryに応答して、次はConfigureRequest()です。

private HttpWebRequest ConfigureRequest()
{
    string          sUrl            = CreateURL(bucket, key);
    HttpWebRequest  httpWebRequest  = WebRequest.Create(sUrl) as HttpWebRequest;

    httpWebRequest.AllowWriteStreamBuffering = false;
    httpWebRequest.AllowAutoRedirect = true;
    httpWebRequest.UserAgent = this.m_sUserAgent;
    httpWebRequest.Method = "GET";
    httpWebRequest.Timeout = this.m_iTimeout;

    // *** NB: This line was left out of my original posting, and turned out to be
    // crucial
    if (m_contentLength > 0)
        httpWebRequest.ContentLength = m_contentLength;

    httpWebRequest.Headers.Add(StaticValues.Amazon_AlternativeDateHeader, timestamp);
    httpWebRequest.Headers.Add(StaticValues.HttpRequestHeader_Authorization, StaticValues.Amazon_AWS + " " + aWSAccessKeyId + ":" + signature);

    return httpWebRequest;
}

編集:検証していないコードを質問から削除するという根本的な罪を犯したことが、問題とは無関係であることがわかりました。次の行を削除しました。

    if (m_contentLength > 0)
        httpWebRequest.ContentLength = m_contentLength;

gETリクエストにはcontent-lengthが指定されないと思ったからです。私が間違っていたことがわかりました。この行を削除すると、問題が修正されます。

私が今持っている唯一の質問はなぜですか? Ithink指定されたコンテンツの長さは正しいと思いますが、1つずれている可能性があります。短すぎるコンテンツの長さを指定すると、完全なダウンロードが行われなくなり、接続が開いたままになりますか?とにかく、Close()やDispose()が接続を切断するはずだと思っていたでしょう。

26
Tim Martin
httpWebRequest.Abort(); // before you leave

解決します!

resource を見てください。

10
Diogo

毎回新しいHttpWebRequestを作成していることを確認してください。 GetResponse メソッドに関するMSDNリファレンスからの引用:

GetResponseを複数回呼び出すと、同じ応答オブジェクトが返されます。要求は再発行されません。

更新1:わかりました。 webResponseStreamも閉じようとした場合はどうでしょうか。現在は閉じていません。webResponseを閉じているだけです(除外しようとしているだけです)。 httpWebResponseも破棄します(WebResponseだけでなく)

更新2:私が提案できる他の唯一のことは、私があなたと同じようなことをしたときに見た次の記事を見てみることです。再実行:
http://arnosoftwaredev.blogspot.com/2006/09/net-20-httpwebrequestkeepalive-and.html
http://www.devnewsgroups.net/dotnetframework/t10805-exception-with-httpwebrequest-getresponse.aspx

私が違うのは、次のことだけです。
-webrequest.KeepAlive = falseを設定します
-構成に接続管理機能がありません(一連の要求を行うためにループしません)

8
AdaTheDev

HttpWebRequest.ContentLength のドキュメントによると:

ContentLengthプロパティの-1以外の値は、リクエストがデータをアップロードし、データをアップロードするメソッドのみがMethodプロパティに設定できることを示します。

ContentLengthプロパティを値に設定した後、そのバイト数を、GetRequestStreamメソッドまたはBeginGetRequestStreamメソッドとEndGetRequestStreamメソッドの両方を呼び出して返される要求ストリームに書き込む必要があります。

コンテンツの長さを設定しているのにデータをアップロードしていないため、ハングしていると思われます。その場合は例外をスローする必要があると思うかもしれませんが、明らかにそうではありません。

1
Jim Mischel

使用してみてください:

         HttpRequestCachePolicy noCachePolicy = new HttpRequestCachePolicy(HttpRequestCacheLevel.NoCacheNoStore);
         httpWebRequest.CachePolicy = noCachePolicy;
0
kris164