Зачем использовать HttpClient для синхронного подключения
Я строю библиотеку классов для взаимодействия с API. Мне нужно вызвать API и обработать ответ XML. Я вижу преимущества использования HttpClient
для асинхронного подключения, но то, что я делаю, является чисто синхронным, поэтому я не вижу каких-либо существенных преимуществ по сравнению с использованием HttpWebRequest
.
Если кто-то может пролить свет, я был бы очень признателен. Я не из тех, кто использует новые технологии ради этого.
Ответы
Ответ 1
но то, что я делаю, является чисто синхронным
Вы можете использовать HttpClient
для синхронных запросов просто отлично:
using (var client = new HttpClient())
{
var response = client.GetAsync("http://google.com").Result;
if (response.IsSuccessStatusCode)
{
var responseContent = response.Content;
// by calling .Result you are synchronously reading the result
string responseString = responseContent.ReadAsStringAsync().Result;
Console.WriteLine(responseString);
}
}
Что касается использования HttpClient над WebRequest, то HttpClient - новый парень на блоке и может содержать улучшения по сравнению с старым клиентом.
Ответ 2
Я бы повторил итерацию Донни В. и Джош
"Единственная причина, по которой я не буду использовать версию async, - это если я пытаюсь для поддержки старой версии .NET, которая еще не построила в асинхронной поддержке."
(и upvote, если бы у меня была репутация.)
Я не могу вспомнить последний раз, когда-либо, я был благодарен факту, что HttpWebRequest бросил исключения для кодов состояния >= 400. Чтобы обойти эти проблемы, вам нужно немедленно поймать исключения и сопоставить их с некоторыми не- механизмы реагирования на исключения в вашем коде... скучные, утомительные и подверженные ошибкам сами по себе. Независимо от того, связано ли это с базой данных или внедрением веб-прокси на заказ, ее "почти" всегда желательно, чтобы драйвер Http просто передал вашему приложению код, что было возвращено, и оставьте его до вас, чтобы решить, как себя вести.
Следовательно, предпочтительнее HttpClient.
Ответ 3
Единственной основной причиной, по которой я использую HttpClient, является то, что она не генерирует исключение, когда 404 возвращается по URL-адресу.
Ответ 4
Если вы создаете библиотеку классов, возможно, пользователи вашей библиотеки хотели бы использовать вашу асинхронную библиотеку. Я думаю, что это самая большая причина.
Вы также не знаете, как будет использоваться ваша библиотека. Возможно, пользователи будут обрабатывать множество и множество запросов, и поэтому асинхронно будет помогать ему работать быстрее и эффективнее.
Если вы можете сделать это просто, постарайтесь не возлагать бремя на пользователей вашей библиотеки, пытаясь сделать поток асинхронным, когда вы можете позаботиться об этом для них.
Единственная причина, по которой я не буду использовать версию async, - это то, что я пытаюсь поддерживать более старую версию .NET, которая еще не имеет встроенной поддержки async.
Ответ 5
В моем случае принятый ответ не сработал. Я вызывал API из приложения MVC, у которого не было асинхронных действий.
Вот как мне удалось заставить его работать:
private static readonly TaskFactory _myTaskFactory = new TaskFactory(CancellationToken.None, TaskCreationOptions.None, TaskContinuationOptions.None, TaskScheduler.Default);
public static T RunSync<T>(Func<Task<T>> func)
{
CultureInfo cultureUi = CultureInfo.CurrentUICulture;
CultureInfo culture = CultureInfo.CurrentCulture;
return _myTaskFactory.StartNew<Task<T>>(delegate
{
Thread.CurrentThread.CurrentCulture = culture;
Thread.CurrentThread.CurrentUICulture = cultureUi;
return func();
}).Unwrap<T>().GetAwaiter().GetResult();
}
Затем я назвал это следующим образом:
Helper.RunSync(new Func<Task<ReturnTypeGoesHere>>(async () => await AsyncCallGoesHere(myparameter)));
Ответ 6
public static class AsyncHelper
{
private static readonly TaskFactory _taskFactory = new
TaskFactory(CancellationToken.None,
TaskCreationOptions.None,
TaskContinuationOptions.None,
TaskScheduler.Default);
public static TResult RunSync<TResult>(Func<Task<TResult>> func)
=> _taskFactory
.StartNew(func)
.Unwrap()
.GetAwaiter()
.GetResult();
public static void RunSync(Func<Task> func)
=> _taskFactory
.StartNew(func)
.Unwrap()
.GetAwaiter()
.GetResult();
}
затем
AsyncHelper.RunSync(() => DoAsyncStuff());
если вы используете этот класс, передайте свой асинхронный метод в качестве параметра, вы можете безопасно вызывать асинхронные методы из методов синхронизации.
это объясняется здесь: https://cpratt.co/async-tips-tricks/