0

I have an Async task that I am using to call a method that then will return a boolean.

   public async Task LoginAsync(){

            await Task.Run(() =>
            {
                CheckUsernameLogin();
            });
        }

I am also updating the GUI elsewhere while this is happening. I want to use LoginAsync() to assign a value to a boolean i.e bool x = LoginAysnc();. I have tried making the async method look something like this

   public async Task<bool> LoginAsync(){

            return await Task.Run(() =>
            {
                CheckUsernameLogin();
            });
        }

then tried to assign the return value with something like this bool x = LoginAsync.Result; but that deadlocks my app. I am doing it this way to check if the username login credentials (determined by CheckUsernameLogin) are valid while also updating the GUI to hold a progress bar. I want to use the returned boolean value to create AlertDialogs based on the validity of the credentials. Im very frustrated and stuck. Thanks in advance.

EDIT!

Here is the other method. Some users suggested making CheckUsernameLogin async, but I don't know where I would but the await calls. I also know that my AlertDialogs will not work because I am using this method in an async way or something like that. Im VERY new to await/sync stuff. Thanks guys.

 public async Task<bool> CheckUsernameLogin(){
        MySqlConnection connection = new MySqlConnection("Top Secret Server Stuff");
        connection.Open();
        username = FindViewById <TextView>(Resource.Id.username_field).Text;
        TriTrack.Utils.Settings.LastUsername = FindViewById<TextView>(Resource.Id.username_field).Text;
        password = FindViewById<TextView>(Resource.Id.password_field).Text;
        TriTrack.Utils.Settings.LastPassword = FindViewById<TextView>(Resource.Id.password_field).Text;
        string user_password;
        List<string> names = new List<string>();
        var command = connection.CreateCommand();
        command.CommandText = ("SELECT username FROM users where username=@username;");
        command.Parameters.AddWithValue("@username", username);
        MySqlDataReader username_reader = command.ExecuteReader();
        while (username_reader.Read())
        {
            names.Add(username_reader.GetString("username"));
        }
        username_reader.Close();
        if (names.Count != 1){
            ShowAlert();
            return false;
        }
        else{
            command.CommandText = ("SELECT password FROM users where username=@username;");
            command.Parameters.AddWithValue("@username", username);
            MySqlDataReader password_reader = command.ExecuteReader();
            password_reader.Read();
            user_password = password_reader.GetString(0);
            if(user_password == password){
                Intent intent = new Intent(this, typeof(MapsActivity));
                this.StartActivity(intent);
                return true;
            }
            else{
                ShowAlert();
            }
        }
        return false;
    }
B. Morris
  • 75
  • 1
  • 7

3 Answers3

0

Follow the steps to achieve your result:

  1. Fire up an animation to show progress. A rotating cog (my personal preference) is better than a progress bar. e.g. ShowRotatingCog();

  2. Fire your Login user asynchronously using bool x = await CheckUsernameLogin();

  3. Show the result of the asynchronous operation after hiding the cog. e.g. HideRotatingCog(); if(x) Alert("Login Successful"); else Alert("Invalid Login");

Enoch Olaoye
  • 144
  • 1
  • 6
  • @B.Morris I can't comment under your post because I don't have the required reputation. You should not be showing the alerts inside the CheckUsernameLogin method. Do it in a separate method that calls the CheckUsernameLogin method. You should also supply the username and password to the CheckUsernameLogin method rather than accessing them directly. It enables you to separate your code and be able to debug and test your code better. – Enoch Olaoye May 27 '18 at 22:23
-1

Looks like you're trying to return the result of a sync method from an async. If this assumption is correct, then you can write

public async Task<bool> LoginAsync() => await Task.FromResult<bool>(CheckUsernameLogin());

private bool CheckUsernameLogin() => true; 
Ess
  • 99
  • 1
  • 4
  • Thanks for the answer but Im not sure I understand... How does this allow me to assign the value from the sync method to a variable I can use in my main function? – B. Morris May 27 '18 at 21:14
  • You can do the following public static void Main(string [] args) { var result = LoginAsync().Result; } – Ess May 27 '18 at 21:16
  • If I do that, the GUI only updates after CheckUsernameLogin() has run fully. Any other suggestions? – B. Morris May 27 '18 at 21:23
-1
public async Task<bool> LoginAsync()
{
    bool result = await CheckUsernameLogin();
    return result;
}
Max von Hippel
  • 2,856
  • 3
  • 29
  • 46
  • 1
    Hi Miguel and welcome to Stack Overflow! Code-only answers are discouraged on Stack Overflow. Could you maybe edit your answer to additionally include an English written explanation of why or how your code solves the problem? – Max von Hippel May 31 '18 at 15:41