使用.NET通过HTTP下载文件的最佳方法是什么?

时间:2010-03-24 05:09:07

标签: c# .net http webclient

在我的一个应用程序中,我使用WebClient类从Web服务器下载文件。有时,应用程序会根据Web服务器下载数百万个文档。似乎有很多文档时,WebClient不能很好地扩展性能。

此外,似乎WebClient即使在成功下载特定文档后也不会立即关闭为WebServer打开的连接。

我想知道我还有其他选择。

更新: 此外,我注意到每次下载WebClient都会执行身份验证握手。由于我的应用程序只与单个Web服务器进行通信,因此我期待看到此握手一次。 WebClient的后续调用是否应该重用身份验证会话?

更新:我的应用程序还调用了一些Web服务方法,对于这些Web服务调用,似乎重用了身份验证会话。此外,我正在使用WCF与Web服务进行通信。

4 个答案:

答案 0 :(得分:5)

我认为您仍然可以使用“WebClient”。但是,最好使用“使用”块作为一种好的做法。这将确保关闭对象并将其处理掉: -

using(WebClient client = new WebClient()) {
// Use client
} 

答案 1 :(得分:2)

我打赌你的每台服务器的默认限制为2个连接。尝试在程序开头运行此代码:

var cme = new System.Net.Configuration.ConnectionManagementElement();
cme.MaxConnection = 100;
System.Net.ServicePointManager.DefaultConnectionLimit = 100;

答案 2 :(得分:0)

我注意到我正在处理的另一个项目中的会话行为相同。为了解决这个“问题”,我确实使用了静态CookieContainer(因为客户端的会话被保存在cookie中的值识别)。

public static class SomeStatics
{ 
    private static CookieContainer _cookieContainer;
    public static CookieContainer CookieContainer
    {
         get
         {
             if (_cookieContainer == null)
             {
                 _cookieContainer = new CookieContainer();
             }
            return _cookieContainer;
         }
    }
}

public class CookieAwareWebClient : WebClient
{ 
    protected override WebRequest GetWebRequest(Uri address)
    {
        WebRequest request = base.GetWebRequest(address);
        if (request is HttpWebRequest)
        {
            (request as HttpWebRequest).CookieContainer = SomeStatics.CookieContainer;
            (request as HttpWebRequest).KeepAlive = false;
        }
        return request;
    }
}

//now the code that will download the file
using(WebClient client = new CookieAwareWebClient())
{
    client.DownloadFile("http://address.com/somefile.pdf", @"c:\\temp\savedfile.pdf");
}

代码只是一个示例,受到Using CookieContainer with WebClient classC# get rid of Connection header in WebClient的启发。

以上代码将在文件下载后立即关闭您的连接,并将重复使用身份验证。

答案 3 :(得分:-1)

WebClient可能是最好的选择。由于某种原因,它不会立即关闭连接:因此它可以再次使用相同的连接,而无需打开新连接。如果您发现它没有按预期重复使用连接,那通常是因为您没有Close()来自先前请求的响应:

var request = WebRequest.Create("...");
// populate parameters

var response = request.GetResponse();
// process response

response.Close(); // <-- make sure you don't forget this!