Why use HttpClient for Synchronous Connection

前端 未结 5 1390
傲寒
傲寒 2020-11-28 01:38

I am building a class library to interact with an API. I need to call the API and process the XML response. I can see the benefits of using HttpClient for Async

相关标签:
5条回答
  • 2020-11-28 02:15
    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();
    }
    

    Then

    AsyncHelper.RunSync(() => DoAsyncStuff());
    

    if you use that class pass your async method as parameter you can call the async methods from sync methods in a safe way.

    it's explained here : https://cpratt.co/async-tips-tricks/

    0 讨论(0)
  • 2020-11-28 02:17

    but what i am doing is purely synchronous

    You could use HttpClient for synchronous requests just fine:

    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);
        }
    }
    

    As far as why you should use HttpClient over WebRequest is concerned, well, HttpClient is the new kid on the block and could contain improvements over the old client.

    0 讨论(0)
  • 2020-11-28 02:22

    If you're building a class library, then perhaps the users of your library would like to use your library asynchronously. I think that's the biggest reason right there.

    You also don't know how your library is going to be used. Perhaps the users will be processing lots and lots of requests, and doing so asynchronously will help it perform faster and more efficient.

    If you can do so simply, try not to put the burden on the users of your library trying to make the flow asynchronous when you can take care of it for them.

    The only reason I wouldn't use the async version is if I were trying to support an older version of .NET that does not already have built in async support.

    0 讨论(0)
  • 2020-11-28 02:31

    In my case the accepted answer did not work. I was calling the API from an MVC application which had no async actions.

    This is how I managed to make it work:

    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();
        }
    

    Then I called it like this:

    Helper.RunSync(new Func<Task<ReturnTypeGoesHere>>(async () => await AsyncCallGoesHere(myparameter)));
    
    0 讨论(0)
  • 2020-11-28 02:34

    I'd re-iterate Donny V. answer and Josh's

    "The only reason I wouldn't use the async version is if I were trying to support an older version of .NET that does not already have built in async support."

    (and upvote if I had the reputation.)

    I can't remember the last time if ever, I was grateful of the fact HttpWebRequest threw exceptions for status codes >= 400. To get around these issues you need to catch the exceptions immediately, and map them to some non-exception response mechanisms in your code...boring, tedious and error prone in itself. Whether it be communicating with a database, or implementing a bespoke web proxy, its 'nearly' always desirable that the Http driver just tell your application code what was returned, and leave it up to you to decide how to behave.

    Hence HttpClient is preferable.

    0 讨论(0)
提交回复
热议问题