Каков наилучший способ загрузки файлов через HTTP с помощью .NET? - PullRequest
2 голосов
/ 24 марта 2010

В одном из моих приложений я использую класс WebClient для загрузки файлов с веб-сервера. В зависимости от веб-сервера иногда приложение загружает миллионы документов. Кажется, что, когда документов много, производительность WebClient не увеличивается.

Также, похоже, что WebClient не сразу закрывает открытое соединение с WebServer даже после успешной загрузки определенного документа.

Я хотел бы знать, какие у меня есть альтернативы.

Обновление: Также я заметил, что для каждой загрузки WebClient выполняет рукопожатие аутентификации. Я ожидал увидеть это рукопожатие один раз, так как мое приложение взаимодействует только с одним веб-сервером. Разве последующие вызовы WebClient не должны повторно использовать сеанс аутентификации?

Обновление: Мое приложение также вызывает некоторые методы веб-службы, и для этих вызовов веб-службы кажется, что сеанс аутентификации используется повторно. Также я использую WCF для связи с веб-сервисом.

Ответы [ 4 ]

5 голосов
/ 24 марта 2010

Я думаю, что вы все еще можете использовать "WebClient". Тем не менее, вам лучше использовать блок «использование» в качестве хорошей практики. Это обеспечит закрытие и удаление объекта: -

using(WebClient client = new WebClient()) {
// Use client
} 
2 голосов
/ 24 марта 2010

Бьюсь об заклад, у вас установлен предел по умолчанию 2 подключения на сервер Попробуйте запустить этот код в начале вашей программы:

var cme = new System.Net.Configuration.ConnectionManagementElement();
cme.MaxConnection = 100;
System.Net.ServicePointManager.DefaultConnectionLimit = 100;
0 голосов
/ 24 марта 2010

Я заметил такое же поведение с сеансом в другом проекте, над которым я работал. Чтобы решить эту «проблему», я использовал статический 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");
}

Код является лишь примером и вдохновлен на Использование CookieContainer с классом WebClient и C # избавляет от заголовка Connection в WebClient .

Приведенный выше код закроет ваше соединение сразу после загрузки файла и будет повторно использовать аутентификацию.

0 голосов
/ 24 марта 2010

WebClient, вероятно, лучший вариант. По какой-то причине он не закрывает соединение сразу, поэтому он может снова использовать то же соединение без необходимости открывать новое. Если вы обнаружите, что оно не использует соединение должным образом, обычно это происходит потому, что вы не Close() получаете ответ от предыдущего запроса:

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

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

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