12

によって作成された接続を閉じる方法を見つけるのに問題がありWebClientます。新しいWebClientオブジェクトを作成してDownloadFileからメソッドを何度も呼び出しますが、呼び出しごとに常に新しい接続が作成され、それらの接続は開いたままになります (確立された状態)。確立されたすべての接続を TCPView で確認できます。

Webclient. _ ダウンロードが完了した後に接続を強制的に閉じるにはどうすればよいですか?

私はすでに WebClient を派生させ、キープアライブを手動で false に設定しようとしましたが、アプリの構成でも十分な接続が許可されています。

<connectionManagement>
  <add address="*" maxconnection="1000"/>
</connectionManagement>
4

1 に答える 1

22

簡単な答え: 接続を手動で閉じる必要はありません。それらは舞台裏で管理されています。

HTTP/1.1 接続は、同じサーバーへの複数の要求がよりタイムリーかつ効率的な方法で処理されるように (単一のサイトから複数のファイルを要求する Web ブラウザーなど)、要求が完了してもすぐには閉じられません。しばらくするとタイムアウトするため、これについて心配したり、手動で閉じたりする必要はありません。エラーを引き起こしていますか?

WebClientそれが問題である場合は、メソッドを継承してオーバーライドしGetWebRequestて手動で設定することができますKeepAlive。たとえば、次のようになります。

public class NoKeepAlivesWebClient : WebClient
{
    protected override WebRequest GetWebRequest(Uri address)
    {
        var request = base.GetWebRequest(address);
        if (request is HttpWebRequest)
        {
            ((HttpWebRequest)request).KeepAlive = false;
        }

        return request;
    }
}

また、次のパターンを使用することを常にお勧めしますWebClient

using (var client = new NoKeepAlivesWebClient())
{
    // Some code
}

最後に、HTTP/1.1 での永続的な接続に関する RFC 情報を次に示します。

http://www.w3.org/Protocols/rfc2616/rfc2616-sec8.html

より親しみやすいウィキペディアのエントリ:

http://en.wikipedia.org/wiki/HTTP_persistent_connection

編集:

申し訳ありません。あなたの編集された質問から、あなたはすでに上記のようなことを試みましたが、成功していないことがわかります。

ただし、問題を再現できませんでした。を使用して小さなプログラムを作成し、NoKeepAlivesWebClientTCPView によると、使用後に接続を正常に閉じました。

static void Main(string[] args)
{
    // Random test URLs
    var urls = new List<string> {
        "http://msdn.microsoft.com/en-us/library/tt0f69eh.aspx",
        "http://msdn.microsoft.com/en-us/library/system.net.webclient.allowreadstreambuffering.aspx",
        "http://msdn.microsoft.com/en-us/library/system.net.webclient.allowwritestreambuffering.aspx",
        "http://msdn.microsoft.com/en-us/library/system.net.webclient.baseaddress.aspx",
        "http://msdn.microsoft.com/en-us/library/system.net.webclient.cachepolicy.aspx",
        "http://msdn.microsoft.com/en-us/library/system.net.webclient.credentials.aspx",
        "https://www.youtube.com/",
        "https://www.youtube.com/feed/UClTpDNIOtgfRkyT-AFGNWVw",
        "https://www.youtube.com/feed/UCj_UmpoD8Ph_EcyN_xEXrUQ",
        "https://www.youtube.com/channel/UCn-K7GIs62ENvdQe6ZZk9-w" };

    using (var client = new NoKeepAlivesWebClient())
    {
        // Save each URL to a Temp file
        foreach (var url in urls)
        {
            client.DownloadFile(new Uri(url), System.IO.Path.GetTempFileName());
            Console.WriteLine("Downloaded: " + url);
        }
    }
}

同じ問題について別の SO の質問があります。

C# は WebClient の Connection ヘッダーを取り除きます

于 2013-05-11T22:06:51.797 に答える