Зачем использовать 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/