Tasks don't run asynchronously

Hi, i have a problem, after pressing button i have a simple "timeout" while loop. It should, for 10 seconds, wait for connection task to complete, but task completes after while loop ends :/ Nothing happens while loop runs.

namespace wdw_mobile_client
{
    [XamlCompilation(XamlCompilationOptions.Compile)]
    public partial class LoginPage : ContentPage
    {
        private bool? isConnected = null;
        private bool loggedIn = false;
        private HttpClient _client;
        public User student;
        private ActivityIndicator activityIndicator;
        public static NavigationPage page;
        public DateTimeOffset startTime;
        Task connection;

        public LoginPage ()
        {
            InitializeComponent ();
            _client = new HttpClient();
            activityIndicator = indicator;
        }

        protected override void OnAppearing()
        {
            base.OnAppearing();

            connection = hasConnection();
        }

        private async void LoginBtn_Clicked(object sender, EventArgs e)
        {
            loginBtn.IsEnabled = false;
            //string id = student_id.Text;
            //string pass = password.Text;
            string id = "developer";
            string pass = "developer";

            string jsonString = $"{{ \"username\":\"{id}\", \"password\":\"{pass}\" }}";

            DateTimeOffset startTime = DateTimeOffset.Now;

            while (DateTimeOffset.Now.Subtract(startTime).TotalMilliseconds < 10000 & isConnected == null)
            {
                if (connection.IsCompleted)
                {
                    student_id.IsEnabled = false;
                    password.IsEnabled = false;
                    await getToken(jsonString);
                    if (loggedIn)
                    {
                        page = new NavigationPage(new LectureListPage(student));
                        App.Current.MainPage = page;
                    }
                }
            }
            loginBtn.IsEnabled = true;
            await DisplayAlert("Powiadomienie", "Brak połączenia z internetem.", "OK");
        }

        public async Task hasConnection()
        {
            try {
                HttpResponseMessage response = await _client.GetAsync("xxxx://xxxx.xxxxxxxxx.xxx/");
                isConnected = true;
                Console.WriteLine("Connected!");
            }
            catch(Exception e)
            {
                isConnected = false;
                Console.WriteLine("No connection! \n" + e);
            }
        }

        public async Task getToken(dynamic jsonString)
        {
            indicator.IsRunning = true;

            try
            {
                var stringContent = new StringContent(jsonString, Encoding.UTF8, "application/json");
                HttpResponseMessage response = await _client.PostAsync("xxxx://xxxxxx.xxxxxxxxxx.xxx/xxxxx_xxxxx", stringContent);
                response.EnsureSuccessStatusCode();
                string responseJson = await response.Content.ReadAsStringAsync();
                student = JsonConvert.DeserializeObject<User>(responseJson);
                loggedIn = true;
                //Console.WriteLine("This is the token: " + student.token);
            }
            catch(HttpRequestException e)
            {
                await DisplayAlert("Błąd", "Niepoprawny nr. indeksu lub hasło.", "OK");
                Console.WriteLine("Wrong id or password! \n" + e);
                loginBtn.IsEnabled = true;
                student_id.IsEnabled = true;
                password.IsEnabled = true;
            }
            catch (JsonReaderException e)
            {
                Console.WriteLine("Json error! \n" + e);
            }

            indicator.IsRunning = false;
        }

        private void NextEntry(object sender, EventArgs e)
        {
            password.Focus();
        }
    }
}

Best Answer

  • Accepted Answer

    Turns out, all i had to do was await connection in while loop before if statement. App works fast and well now. Thank you for trying to help me.

Answers

  • ClintStLaurentClintStLaurent USUniversity ✭✭✭✭✭

    So many issues...

    • Its all in the UI code behind
    • Directly whacking with the UI elements by name from the code behind
    • Your HTTPResponses aren't being disposed or taking place inside using blocks... probably getting blocked and sometimes just never returning at all
    • Its all taking place on the UI thread
    • Single & in your While statement (bool additive, not comparison taking place)
    • All fields, no properties... So I'm guessing no MVVM in use

    I think you should count yourself lucky it runs at all.

    There are clearly several concepts there that are new to you. I'd suggest trying to learn one at a time instead of throwing them all into an app at once. There's just so many things wrong here its going to be hard to put your finger on any single cause of an issue.

  • stanislaw_borkowskistanislaw_borkowski Member ✭✭
    edited April 10

    @ClintStLaurent
    Ok, thanks, now im using using-block. Never heard of it before, even though im writing my app with docs.
    Single & was a bug introduced by trying to make this run asynchronously, my bad.
    Im not using any patterns for now, i will probably use them after i have a running app, as a process of improving stability etc.
    I was trying to avoid running everything on 1 thread, i thought tasks run on separate threads :/ Documentation is really "not good" or maybe im just too stupid.
    There is no problem with accessing and signing to variable object from xaml, i have never encountered anyone who would say otherwise (at least its not a problem now).
    Can you help me run my task on different threads/ make them run asynchronously?

  • stanislaw_borkowskistanislaw_borkowski Member ✭✭
    Accepted Answer

    Turns out, all i had to do was await connection in while loop before if statement. App works fast and well now. Thank you for trying to help me.

Sign In or Register to comment.