В чем разница между HttpClient и WebClient?
Да, я знаю, что эта тема мелькала много раз. Я знаю, что WebClient это обертка для более старого HttpWebRequest. Знаю, что HttpClient - это более новый API для работы с HTTP.
У меня возникла задача. Есть сервис. Он ждет задачи из очереди. Ему прилетает задача, содержащая методанные. Среди этих методанных есть URL, по которому лежит файл, который надо оценить по размеру (валидировать) и скачать. Я провел ресерч в и понял, что для задач по типу "скачать файл" почти всегда советуют именно WebClient. Вопрос в том, есть ли в рамках данной задачи (повторюсь, просто скачать файл, предварительно получив его размер) какие-либо преимущества у HttpClient перед WebClient? Если есть, то, пожалуйста, назовите, какие.
Ответы (2 шт):
Смысл всего вопроса в том, что когда вы выполняете операцию ввода-вывода, у вас 2 пути, либо блокировать намертво выполняющий операцию поток, либо не блокировать. Выбор по идее должен быть основан именно на этом, а не на том "как скачать файл" - ведь это не единственная задача перед вами в плане работы с сетью, верно?
Вот так это делается с помощью HttpClient.
private static readonly HttpClient client = new HttpClient();
Можно так
private async Task DownLoadFile()
{
using var stream = await client.GetStreamAsync("https://url");
using var fs = File.Create("file.txt");
await stream.CopyToAsync(fs);
}
или если файл небольшой, то даже так
await File.WriteAllBytesAsync("file.txt", await client.GetBytesAsync("https://url"));
Как видите, если читать документацию, можно много всякого найти. Ну и количество строк кода от того, что вы решились использовать HttpClient точно не увеличится, а вот возможностей станет больше.
Многим поначалу страшно работать с асинхронностью, но она на самом деле не простая для понимания, но поднапрячься и освоить - оно того точно стоит. Начните с этого: Асинхронное программирование.
В чем разница между HttpClient и WebClient?
Первый современный и асинхронный, второй - устаревший и синхронный.
Про разницу в качестве реализации протокола, поддержке HttpClient HTTP/2 и прочих современных технологий я даже молчу. Ну и скорость работы у него также выше, особенно при множественных одновременных запросах к серверу.
К тому же именно HttpClient рекомендован Microsoft для новой разработки, все остальные HttpWebRequest, WebRequest, WebClient считаются устаревшими.
Мы не рекомендуем использовать
WebClientкласс для новой разработки. Вместо этого используйтеSystem.Net.Http.HttpClientкласс.
Другими словами, заданный вами вопрос - даже не спорный. Вы же не спрашиваете, какой вам феймворк использовать для нового проекта: 3, 4 или 5. Очевидно, вы возьмете посвежее. Вот и с клиентами этими то же самое.
Бегло просмотрев методы, я заметил один очень существенный недостаток "древнего" метода: отсутствие встроенного метода возврата в основной поток. Сплошные вопрос-ответы: IsBusy, Completed, Changed и так далее. Основной поток придётся крутить в цикле или использовать ещё более сложные методы. Морока.
В новом методе это делается просто. (downloadTask).Wait()!!! (Powershell):
# https://adamtheautomator.com/powershell-download-file/
[void][Reflection.Assembly]::LoadWithPartialName("System.Net")
[void][Reflection.Assembly]::LoadWithPartialName("System.Net.Http")
$source = 'https://speed.hetzner.de/100MB.bin' # Set the source and destination
$destination = "$env:TEMP\100MB.bin"
# Create the HTTP client download request
$httpClient = New-Object System.Net.Http.HttpClient
$response = $httpClient.GetAsync($source)
$response.Wait()
# Create a file stream to pointed to the output file destination
$outputFileStream = [System.IO.FileStream]::new($destination, [System.IO.FileMode]::Create, [System.IO.FileAccess]::Write)
# Stream the download to the destination file stream
$downloadTask = $response.Result.Content.CopyToAsync($outputFileStream)
# вставляй любой код, следующий Wait остановит поток и будет ждать результата или выдаст его сразу (если он получен) и продолжит выполнение кода дальше
$downloadTask.Wait() # Вот где вся закорючка!!!
# Close the file stream
$outputFileStream.Close()
То есть, если ваша задача - выполнил и забыл, выбирайте старый метод без всяких awaitов - они ему не нужны. (да и ждать его мы всё равно не собираемся)
Если нужны дальнейшие действия с результатом, то новый. (Скорее всего, так и будет, не проверял без выполненного Wait() не будут освобождены ресурсы, что в итоге, при многократном использовании метода, окажется плачевным)