none
HTTPClient in C# -- Crashes inexplicably RRS feed

  • Question

  • I've been trying to figure out how to use the HTTPClient class in my C# efforts.  I've found several examples on youtube that all use similar code and I see it all work for the creators of those videos.  As best I can tell, my code is exactly the same as the code in one of those videos.  But yet even though it worked in the video, every time I run it, it crashes.

    I'm at a complete loss as to why it fails for me but worked in the video.

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Net.Http; namespace ConsoleApp2 { class Program { static void Main(string[] args) { //I placed a breakpoint at this line and stepped through the rest of the code......... GetRequest("http://www.google.com"); } async static void GetRequest(String URL) { using (HttpClient client = new HttpClient()) {

    // As soon as I try to step over (or even into) this next line, it crashes. using (HttpResponseMessage response = await client.GetAsync(URL)) { using (HttpContent content = response.Content) { string data = await content.ReadAsStringAsync(); Console.WriteLine(data); } } } Console.ReadKey(); } } }



    Don


    • Edited by BigDon49 Saturday, July 8, 2017 4:02 PM Make it easier to read.
    Saturday, July 8, 2017 4:00 PM

Answers

  • Hi Don,

    You code around HttpClient is not causing the crash. The issue is your main thread exits before your http client async operation finishes. Try this instead:

            static void Main(string[] args)
            {
                GetRequest("http://www.google.com").Wait();
            }
    
            async static Task GetRequest(String URL)
            {
                using (HttpClient client = new HttpClient())
                {
                    // As soon as I try to step over (or even into) this next line, it crashes.
                    using (HttpResponseMessage response = await client.GetAsync(URL))
                    {
                        using (HttpContent content = response.Content)
                        {
                            string data = await content.ReadAsStringAsync();
    
                            Console.WriteLine(data);
                        }
                    }
                }
                Console.ReadKey();
            }

    2 spots changed:

    1. Change your code GetRequest to return task than void;

    2. Add .Wait() in your caller to maintain the main thread.

    ======

    There's a lot of async operations around the network access. I'll suggest you prepare yourself with skills around C# async operations.



    I build UWPs: Arrnage Pro, Cloud Resource Tools


    • Edited by Saar Shen Saturday, July 8, 2017 6:23 PM
    • Marked as answer by BigDon49 Sunday, July 9, 2017 5:30 AM
    Saturday, July 8, 2017 6:20 PM

All replies

  • The problem is the way you're calling the GetRequest() method from the static Main. I first tried it in a little test app I have (WinForm), calling it from a button click and it worked OK. Next, I called it, as you did, from the static Main and had the same problem you had, with it crashing. I forget the reason why (something to do with async being called from static I think).

    If you still want to test it from a Console app, create a TestClass, put the method in the TestClass, instantiate it, then call another method that is *not* static (which calls yours static method). Or just remove static from the GetRequest() method all together, but it still has to be called from with an instance of a class, not directly from the static Main.

    UPDATE: Oops, I had renamed your async method when I was testing my own, and I forgot to get all the names back in sync (pun intended ... hehehe).  Anyway, I edited the code below to fix it. In my TestThis() method, I was calling TestGetRequest(http://www.google.com) when it should have been calling GetRequest(http://www.google.com).

    static void Main(string[] args)
    {
            testStuff = new TestStuff();
            testStuff.TestThis();
    }
    public class TestStuff
    {
        public void TestThis()
        {
            GetRequest("http://www.google.com");
        }
        
        // this is the same code you have
        async static void GetRequest(String URL)
        {
            using (HttpClient client = new HttpClient())
            {
    
                // As soon as I try to step over (or even into) this next line, it crashes.
                using (HttpResponseMessage response = await client.GetAsync(URL))    
                {
                    using (HttpContent content = response.Content)
                    {
                        string data = await content.ReadAsStringAsync();
    
                        Console.WriteLine(data);
                    }
                }
            }
            Console.ReadKey();
        }
    }            


    ~~Bonnie DeWitt [C# MVP]

    http://geek-goddess-bonnie.blogspot.com



    Saturday, July 8, 2017 5:02 PM
    Moderator
  • Hi Don,

    You code around HttpClient is not causing the crash. The issue is your main thread exits before your http client async operation finishes. Try this instead:

            static void Main(string[] args)
            {
                GetRequest("http://www.google.com").Wait();
            }
    
            async static Task GetRequest(String URL)
            {
                using (HttpClient client = new HttpClient())
                {
                    // As soon as I try to step over (or even into) this next line, it crashes.
                    using (HttpResponseMessage response = await client.GetAsync(URL))
                    {
                        using (HttpContent content = response.Content)
                        {
                            string data = await content.ReadAsStringAsync();
    
                            Console.WriteLine(data);
                        }
                    }
                }
                Console.ReadKey();
            }

    2 spots changed:

    1. Change your code GetRequest to return task than void;

    2. Add .Wait() in your caller to maintain the main thread.

    ======

    There's a lot of async operations around the network access. I'll suggest you prepare yourself with skills around C# async operations.



    I build UWPs: Arrnage Pro, Cloud Resource Tools


    • Edited by Saar Shen Saturday, July 8, 2017 6:23 PM
    • Marked as answer by BigDon49 Sunday, July 9, 2017 5:30 AM
    Saturday, July 8, 2017 6:20 PM
  • Hi Don,

    In case you missed that I edited my original reply (to fix a typo), I thought I'd reply again to alert you to the fact. You probably would have figured it out anyway, but I thought I should let you know.


    ~~Bonnie DeWitt [C# MVP]

    http://geek-goddess-bonnie.blogspot.com

    Saturday, July 8, 2017 9:05 PM
    Moderator
  • Arrgghhh! You're right, @ritehere ... that's what I get for I copy/pasting from my test app. The testStuff variable is declared outside the static Main in my test app, and I forgot to include it in the code I posted. So, yeah, it should have been:

    static void Main(string[] args)
    {
        TestStuff testStuff = new TestStuff();
        testStuff.TestThis();
    }
    


    ~~Bonnie DeWitt [C# MVP]

    http://geek-goddess-bonnie.blogspot.com

    Sunday, July 9, 2017 5:11 AM
    Moderator
  • Thanks everyone for the assistance.  I realize this is an advanced topic -- which is why I'm trying to learn it and at the moment only doing it in a console app.  I'm just trying to learn how it all works at the moment.

    I will eventually be building it into a separate class that will be attached to a large project.

    Here's a link to one of the youtube videos that I was watching.  As best I could tell, my code was EXACTLY the same as shown in the video but the video showed the code working.  If you go to about the 12:30 mark, you'll see his code looks just like what I posted in my original message.  But yet when he ran it, it worked fine.  I'm not trying to argue that I need to be able to use my code as I posted.  I'm just trying to figure out why it's different for me.

    https://www.youtube.com/watch?v=EPSjxg4Rzs8

    And are there any good tutorials out there that will help me understand using the HTTPClient to GET and POST data?  I'm looking to learn not just the mechanics of the actual GET and POST but also how to deal with the error handling.

    I understand the Try...Catch...Fail system to a degree.


    Don


    • Edited by BigDon49 Sunday, July 9, 2017 12:55 PM Added the link that I forgot to include.
    Sunday, July 9, 2017 5:45 AM
  • Thanks everyone for the assistance.  I realize this is an advanced topic -- which is why I'm trying to learn it and at the moment only doing it in a console app.  I'm just trying to learn how it all works at the moment.

    I will eventually be building it into a separate class that will be attached to a large project.

    Here's a link to one of the youtube videos that I was watching.  As best I could tell, my code was EXACTLY the same as shown in the video but the video showed the code working.  If you go to about the 12:30 mark, you'll see his code looks just like what I posted in my original message.  But yet when he ran it, it worked fine.  I'm not trying to argue that I need to be able to use my code as I posted.  I'm just trying to figure out why it's different for me.

    And are there any good tutorials out there that will help me understand using the HTTPClient to GET and POST data?  I'm looking to learn not just the mechanics of the actual GET and POST but also how to deal with the error handling.

    I understand the Try...Catch...Fail system to a degree.


    Don

    Why did you mark that reply as correct answer to your question?

    You want to know why your code crashes inexplicably, rite?

    That reply does not answer your question.

    My reply does!

    Your behavior will not make you understand anything, and will make you ask more questions and get more no answers.

    In case you have not noticed, the usual mvps here don't understand async/await.


    The reply I marked as the answer includes info on what I had to do to get my code working -- when I made the changes it suggested, my code worked.  Yours did not.  When I read his code, I understood why mine was not working (I could tell that it had to do with running asynchronously and I assumed that my MAIN method was quitting too soon.  Therefore, I marked it as the answer.

    The other part of my question (and my follow up question) had to do with my my code didn't work but the code in the video DID work -- even though as best I can tell my code is the SAME as in the video.  NO REPLY in this thread has explained that.  If one were to do that, then yes that would be marked as an answer.


    Don

    Sunday, July 9, 2017 12:53 PM
  • Nearly identical, is the key here. You have the Console.Readkey() in the GetRequest() method. He had the Console.ReadKey() in the Main() method. Try it ...

    ~~Bonnie DeWitt [C# MVP]

    http://geek-goddess-bonnie.blogspot.com

    Sunday, July 9, 2017 2:46 PM
    Moderator
  • Don, if you feel like you are being harassed by any user in the forums then feel free to use the Report as abuse link to report them to the MSDN administrators. This will notify the admins and they can look into the offensive posts. 

    You may mark any post you feel is appropriate as answered. You may mark multiple posts as answered if you like. It is not necessary to mark all posts as answers however, especially if they don't provide any assistance to the question you asked.

    Monday, July 10, 2017 2:05 PM
    Moderator
  • Thanks.
    Thursday, July 11, 2019 12:19 PM