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

C# 使用.NET通过HTTP下载文件的最佳方式是什么?,c#,.net,http,webclient,C#,.net,Http,Webclient,在我的一个应用程序中,我使用WebClient类从web服务器下载文件。根据web服务器的不同,有时应用程序会下载数百万个文档。似乎当有很多文档时,WebClient的性能就不能很好地扩展 此外,WebClient似乎不会立即关闭它为Web服务器打开的连接,即使它成功下载了特定文档 我想知道我还有什么其他选择 更新: 我还注意到,每次下载WebClient都会执行身份验证握手。我希望看到这种握手一次,因为我的应用程序只与单个web服务器通信。WebClient的后续调用不应该重用身份验证会话吗

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

此外,WebClient似乎不会立即关闭它为Web服务器打开的连接,即使它成功下载了特定文档

我想知道我还有什么其他选择

更新: 我还注意到,每次下载WebClient都会执行身份验证握手。我希望看到这种握手一次,因为我的应用程序只与单个web服务器通信。WebClient的后续调用不应该重用身份验证会话吗


更新:我的应用程序还调用了一些web服务方法,对于这些web服务调用,似乎可以重用身份验证会话。我还使用WCF与web服务通信。

WebClient可能是最好的选择。它不会立即关闭连接,这是有原因的:因此它可以再次使用相同的连接,而无需打开新的连接。如果您发现它没有按预期重用连接,这通常是因为您没有
Close()
ing上一个请求的响应:

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

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

response.Close(); // <-- make sure you don't forget this!
var-request=WebRequest.Create(“…”);
//填充参数
var response=request.GetResponse();
//过程响应
response.Close();// 我认为您仍然可以使用“WebClient”。但是,最好使用“using”块作为良好实践。这将确保对象已关闭并已被释放:-

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

我敢打赌,每个服务器的默认连接数是2个。尝试在程序开始时运行以下代码:

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

我在另一个项目中也注意到了同样的行为。为了解决这个“问题”,我使用了一个静态CookieContainer(因为客户端的会话是通过保存在cookie中的值来识别的)

该代码只是一个示例,受和的启发


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

您使用的是异步webclient调用还是同步调用?我使用的是同步调用,但多个线程同时调用不同的webclient调用。我建议只使用一个webclient和异步调用以避免冗余身份验证阶段。我认为webclient不会立即关闭连接,这样您就可以对另一个请求排队。我将WebClient抽象视为一个Web浏览器,在一个Web浏览器中,您可以在不重新验证的情况下完成多个请求。但是,如果每次要下载文件(即使共享cookie)时关闭浏览器并重新打开另一个浏览器,则速度可能会变慢。我正在使用WebClient.DownloadData()下载内容。不确定是否需要在此处显式关闭任何响应对象。我想DownloadData方法在内部为我做这件事。我认为调用WebClient的Dispose方法并没有任何好处。Dispose方法就在那里,因为WebClient继承自组件类。@Shamika:无论如何都要这样做。如果将来的版本决定利用IDisposable怎么办?不要依赖于实现细节。我尝试过,但每次下载都会看到WebClient身份验证握手。仅供参考,我正在使用集成windows身份验证与SharePoint服务器通信。关于:client.Credentials=new NetworkCredential(“用户名”、“密码”)?
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");
}