none
Help With Async/Await RRS feed

  • Question

  • I want to return the data from my API call.  This is my syntax but no data is returned.  I assume this is dued to me improperly using the Asyn/Await keywords.

    Can a more skilled C# dev assist me here?

    public MainPage()
    {
    	InitializeComponent();
    	QueryThatDBAsync();
    }
    
    private async Task QueryThatDBAsync()
    {
    	string URL = "https://sodadb.com/api.php?i=cKtENddsareabdsgfdgf";
    
    	HttpClient httpClient = new HttpClient();
    	HttpResponseMessage response = await httpClient.GetAsync(new Uri(URL));
    
    	if (response.IsSuccessStatusCode)
    	{
    		var content = await response.Content.ReadAsStringAsync();
    		var weatherList = JsonConvert.DeserializeObject<RootObject>(content);
    	}
    }

    Thursday, November 1, 2018 5:28 PM

Answers

  • Your QueryThatDBAsync method is correct. But it returns a Task so the caller needs to wait as well. In your MainPage you aren't awaiting it so MainPage returns before the query is complete. To work around this you'd need to wait on the result.

    public MainPage ()
    {
       InitializeComponent();
    
       QueryThatDBAsync().Wait();
    }

    But I really have a problem with your approach. It isn't going to work out well I believe. You are trying to call an async method in a constructor. That is pretty much a bad idea. Constructors should be short and fast. Making an async call, or any call that takes any amount of time, is not really a good thing to do in the constructor. I would recommend that you move this call to someplace else where the caller can take advantage of the async nature. At this point making QueryThatDBAsync async is pointless because you cannot call it async. Constructors are not allowed to be async in C# at this time.

    Another issue I have with your code is that it looks like a UI element. It is really important to remember that UI elements are not rendered when they are created. That happens later. Until the UI element is rendered (which may be never) you shouldn't do anything that assumes it will be. Hence a constructor call isn't the correct place to be making DB calls (or any async call).

    Given this looks like a UI element I would recommend that you hook into the creation event/method/whatever of the UI element instead (depends upon your framework). When the UI is created then call your async method. Inside your async method it will do its work and, since you aren't configuring await, resume on the UI. So when the UI first loads you can display a "loading" styling and the async method, after it finishes its work, can replace the "loading" with the actual data. But this type of discussion should be based upon the UI framework you're using. I recommend you post this type of question in the appropriate UI forums.


    Michael Taylor http://www.michaeltaylorp3.net

    • Marked as answer by IndigoMontoya Thursday, November 1, 2018 6:31 PM
    Thursday, November 1, 2018 6:25 PM
    Moderator