0

This function works find in a console app:

private async Task TestAsync()
        {
            var client = new RestClient("https://weatherbit-v1-mashape.p.rapidapi.com/current?lang=en&lon=%3Crequired%3E&lat=%3Crequired%3E");
            var request = new RestRequest(Method.GET);
            request.AddHeader("x-rapidapi-host", "weatherbit-v1-mashape.p.rapidapi.com");
            request.AddHeader("x-rapidapi-key", "d6c6-omitted");
            IRestResponse response = await client.ExecuteAsync(request).ConfigureAwait(false);
            return;
        }

But when run inside a xamarin app, this code never finished execution. The task is called, but never finishes. Same thing with every other request I've tried.

Specifications

Xamarin: 4.6.0.1141+555-sha.ec64e9186-azdo.3888486

RestSharp: 106.11.7

Edit:

Here is more code:

class Program
    {
        static void Main(string[] args)
        {
            var x = TestAsync().Result;
            int y = 0;
        }

        private static async Task<IRestResponse> TestAsync()
        {
            var client = new RestClient("https://weatherbit-v1-mashape.p.rapidapi.com/current?lang=en&lon=%3Crequired%3E&lat=%3Crequired%3E");
            var request = new RestRequest(Method.GET);
            request.AddHeader("x-rapidapi-host", "weatherbit-v1-mashape.p.rapidapi.com");
            request.AddHeader("x-rapidapi-key", "d6c61a25cfmshfc1caea2f83287fp1e287cjsn695b47d979fb");
            IRestResponse response = await client.ExecuteAsync(request);
            return response;
        }
    }

this works fine, however the following doesn't work:

public partial class App : Application
    {

        public App()
        {
            InitializeComponent();


            var x = TestAsync().Result;
            int y = 0;

            DependencyService.Register<MockDataStore>();
            MainPage = new AppShell();
        }

        private static async Task<IRestResponse> TestAsync()
        {
            var client = new RestClient("https://weatherbit-v1-mashape.p.rapidapi.com/current?lang=en&lon=%3Crequired%3E&lat=%3Crequired%3E");
            var request = new RestRequest(Method.GET);
            request.AddHeader("x-rapidapi-host", "weatherbit-v1-mashape.p.rapidapi.com");
            request.AddHeader("x-rapidapi-key", "d6c61a25cfmshfc1caea2f83287fp1e287cjsn695b47d979fb");
            IRestResponse response = await client.ExecuteAsync(request);
            return response;
        }

        protected override void OnStart()
        {
        }

        protected override void OnSleep()
        {
        }

        protected override void OnResume()
        {
        }
    }
pseudoabdul
  • 616
  • 3
  • 12
  • 1
    The problem is not with this code, but more than likely how you call it. Which you don't show. My gut feeling is you are calling `Wait`, `Result`, or similar on an `async` method (but its only a guess). If this is not the issue, then it maybe waiting for a timeout and you have connectivity or other issues – TheGeneral Oct 06 '20 at 02:17
  • I've updated the code. You are correct I'm using Result, but its odd that it works in one instance, but not the other. – pseudoabdul Oct 06 '20 at 02:29
  • This is most definitely a duplicate, see this and its duplicates https://stackoverflow.com/questions/64129887/xamarin-forms-how-to-call-an-async-method/64129975#64129975 – TheGeneral Oct 06 '20 at 02:31
  • In regards to your situation, don't do this sort of work in the constructor, do it in an lifecycle event or similar and await the call – TheGeneral Oct 06 '20 at 02:35
  • This is just some dirty code I put together to illustrate the problem. I know It's not ideal, but I think we need to focus on the point that it works in a console app, and not the xamarin app. Any ideas why? I'm not sure its a duplicate, I think their deadlock is caused by using an void async, which I haven't done here. – pseudoabdul Oct 06 '20 at 02:37
  • Yes because the console app has no message pump or dispatcher ergo (no syncronization context). The point is (and this is very prevalent on everything you read), you should never call Result or Wait (or otherwise block) on an async method, there is always a better way, and that usually is await. – TheGeneral Oct 06 '20 at 02:41
  • https://blog.stephencleary.com/2012/07/dont-block-on-async-code.html – TheGeneral Oct 06 '20 at 02:43
  • So if the issue is I'm not using await all the way through, if await can only be called in inside an async function, then how do you call your chain of async functions from the highest level? If you eventually have to get the actual result, instead of just the tasks, surely at the highest point you block the thread until the task has finished execution using .result? – pseudoabdul Oct 06 '20 at 02:52
  • These days frameworks have async methods at the highest level in a lot of cases, also you can use an async void for event handlers, with those 2 you will get 90% of what you need. However there is no such thing as an async constructor, you will need to use a lifecycle event (which is better practice anyway) or run unobserved (not so good) – TheGeneral Oct 06 '20 at 02:54
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/222573/discussion-between-pseudoabdul-and-michael-randall). – pseudoabdul Oct 06 '20 at 02:55
  • Its tempting to start a chat, however there is a wealth of this information written about these issues with the async and await pattern. Now that you know what you are looking for it should be easy to find, good luck :) – TheGeneral Oct 06 '20 at 02:56

0 Answers0