Quantcast
Channel: Recent Threads — Xamarin Community Forums
Viewing all articles
Browse latest Browse all 204402

Severe lag after pressing a button (activity indicator and async REST-calls)

$
0
0

Hi all, this is my first message on this forum and of course, it's about problem I have with my Xamarin app.

I'm a newbie when it comes to Xamarin and I'm building my first app with it. The application is fairly simple (log in to an external system and fetch some data via REST.

When the app opens the user is greeted with a login screen. After giving the credentials and pressing the login-button, 3 things happen in the following order:

1) an activity indicator is shown
2) all the fields and buttons are disabled on the login page
3) authentication and data fetching is done via REST calls to an external system.

The problem is, that after the user presses the login-button, there's a lag of 1 - 4 seconds before anything happens. So it takes 1 - 4 seconds for the activity indicator to pop up and the fields to get disabled. This is quite a horrible user experience and I can't seem to understand why this is happening.

I'm using a CarouselPage and the code for the first page (login page) is simple like this (i removed all formatting for this example):

<ContentPage x:Name="loginPage">
        <ContentPage.Padding>
            <OnPlatform x:TypeArguments="Thickness">
                <On Platform="iOS, Android" Value="0,40,0,0" />
            </OnPlatform>
        </ContentPage.Padding>
        <StackLayout>
            <Image Source="logo" />
            <Label x:Name="authenticationPageLabel"/>
            <Entry x:Name="usernameField" />
            <Entry x:Name="passwordField"/>
            <Button x:Name="logInToSystemButton" Clicked="logInToVaultButton_Clicked" />

            <ActivityIndicator x:Name="loginPageActivityIndicator"
                           Color="Orange"                             
                           VerticalOptions="CenterAndExpand"
                           HorizontalOptions="Fill" />

            <Label x:Name="loginStatusLabel" />
        </StackLayout>
    </ContentPage>

Now the code for the logInToSystemButton click event is like this:

private async void logInToSystem_Clicked(object sender, EventArgs e)
{
            // Show activity indicator and disable buttons/fields
            loginPageActivityIndicator.IsRunning = true;
            logInToSystemButton.IsEnabled = false;
            chkBoxRememberMe.IsEnabled = false;
            usernameField.IsEnabled = false;
            passwordField.IsEnabled = false;
            chkBoxRememberMe.Color = Color.Gray;

            // Get input
            string username = usernameField.Text;
            string password = passwordField.Text;

            // Authentication to the external system
            Task<string> task1 = authenticateToSystemAsync(username, password, GUID);
            authToken = await task1;

            // Get stuff from the system
            Task<List<Stuff>> task2 = GetStuffAsync(authToken);
            listOfStuff.ItemsSource = await task2;

            // Stop activity indicator
            loginPageActivityIndicator.IsRunning = false;

            // Jump to the next carousel page
            CurrentPage = this.Children[1];
}

I've pinpointed the reason for the lag to be the two awaited tasks which make a REST call to the external system. If they are commented out the activity indicator and field disabling happens instantly after the button press. But why is this, since the awaited web-calls happen AFTER the UI stuff in the code and activity indicator is the first line in that click event?


The code example for GetStuffAsync() is something like this:

private static async Task<List<Stuff>> GetStuffAsync(string authToken)
{
            // Create the web request with the passed authToken
            var request = WebRequest.Create($"http://{hostServer}/REST/stuff");
            request.Headers["X-Authentication"] = authToken;
            request.Method = "GET";
            request.Timeout = 30000; // 30 seconds
            request.ContentLength = 0;

            // Get response  
            string result = "";
            using (HttpWebResponse response = await request.GetResponseAsync() as HttpWebResponse)
            {
                // Get the response stream  
                StreamReader reader = new StreamReader(response.GetResponseStream());

                // Read the whole contents and return as a JSON string  
                result = await reader.ReadToEndAsync();
            }

            // Deserialize the returned data
            dynamic lotsOfStuff= JsonConvert.DeserializeObject(result);

            // Iterate over the returned JSON array
            List<Stuff> listOfStuff= new List<Stuff>();
            foreach (dynamic thing in listOfStuff.Items)
            {
                listOfStuff.Add(new Thing { Name = thing.Name, ID = thing.ID });
            }

            return listOfStuff;
}

So of course I'd like the activity indicator and disabling of the fields happen instantly after pressing the login button and then do the other work asynchronously while the user sees the activity indicator spinning. There must be something fundamental I'm doing wrong or missing here. Thank you in advance for reading and helping out.

// TDMR87


Viewing all articles
Browse latest Browse all 204402

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>