首页 > 解决方案 > Xamarin.Forms 中的死锁

问题描述

我的 Xamarin 应用程序有问题。该应用程序对我的网站使用自定义 API。async/await我在方法方面没有太多经验。

以下代码显示 App.xaml.cs:

public partial class App : Application
{
    public static bool IsUserLoggedIn { get; set; }
    public static UserModel currentLoggedInUser { get; set; }

    public static List<ActionTypeModel> listTypes;
    public static List<ActionSubTypeModel> listSubtypes;
    public static List<UserModel> listFriends;
    public static List<List<ActionModel>> listActiveActions;
    public static List<ActionModel> listLastAction;

    public App()
    {
        this.InitializeComponent();

        APIHelper.InitializeClient();

        StartApp().Wait();
    }

    private async Task StartApp()
    {
        //// DEBUG
        //MyAccountStorage.Logout();

        string username = await MyAccountStorage.GetUsername().ConfigureAwait(false);
        string password = await MyAccountStorage.GetPassword().ConfigureAwait(false);
        string user_id = await MyAccountStorage.GetId().ConfigureAwait(false);
        if (username != null && password != null)
        {

            currentLoggedInUser = new UserModel();
            if (user_id != null)
                currentLoggedInUser.user_id = Convert.ToInt32(user_id);
            currentLoggedInUser.username = username;
            currentLoggedInUser.password = password;

            bool isValid = false;
            isValid = await AreCredentialsCorrect(0, currentLoggedInUser.username, currentLoggedInUser.password).ConfigureAwait(false);
            if (isValid)
            {
                IsUserLoggedIn = true;

                await FillLists().ConfigureAwait(false);

                MainPage = new NavigationPage(await MyPage.BuildMyPage().ConfigureAwait(false));
            }
            else
            {
                IsUserLoggedIn = false;

                MainPage = new NavigationPage(await LoginPage.BuildLoginPage().ConfigureAwait(false));
            }

        }
        else
        {
            IsUserLoggedIn = false;

            MainPage = new NavigationPage(await LoginPage.BuildLoginPage().ConfigureAwait(false));
        }
    }

    private async Task FillLists()
    {
        listFriends = await DataControl.GetFriends(App.currentLoggedInUser.user_id, App.currentLoggedInUser.username, App.currentLoggedInUser.password).ConfigureAwait(false);
        if (listFriends == null)
            listFriends = new List<UserModel>();

        listTypes = await DataControl.GetTypes(App.currentLoggedInUser.username, App.currentLoggedInUser.password).ConfigureAwait(false);
        if (listTypes == null)
            listTypes = new List<ActionTypeModel>();

        listActiveActions = new List<List<ActionModel>>();

        for (int i = 0; i < listTypes.Count; i++)
            listActiveActions.Add(await DataControl.GetActiveActions(listTypes[i].action_type_id, currentLoggedInUser.user_id, currentLoggedInUser.username, currentLoggedInUser.password).ConfigureAwait(false));

        listSubtypes = await DataControl.GetSubtypes(App.currentLoggedInUser.username, App.currentLoggedInUser.password).ConfigureAwait(false);
        if (listSubtypes == null)
            listSubtypes = new List<ActionSubTypeModel>();

        listLastAction = await DataControl.GetLastAction(App.currentLoggedInUser.user_id, App.currentLoggedInUser.username, App.currentLoggedInUser.password).ConfigureAwait(false);
        if (listLastAction == null)
            listLastAction = new List<ActionModel>();
    }

    public static async Task<bool> AreCredentialsCorrect(int type, string user, string pass, string nick = "", string email = "")
    {
        List<UserModel> listUsers;

        if (type == 1)
            listUsers = await DataControl.CheckCredentials(1, user, pass, nick, email).ConfigureAwait(false);
        else
            listUsers = await DataControl.CheckCredentials(0, user, pass).ConfigureAwait(false);

        if (listUsers != null)
            if (listUsers.Any())
            {
                currentLoggedInUser = listUsers.First();
                currentLoggedInUser.password = pass;
                return true;
            }

        return false;
    }
}

我在 DataControl.cs 中有 API:

public static async Task<List<UserModel>> CheckCredentials(int type, string username, string pass, string email = "", string nickname = "")
{
    string password = APIHelper.GetHashSha256(pass);

    string url = string.Empty;

    if (type == 0)
        url = APIHelper.ApiClient.BaseAddress + "/account/login.php?username=" + username + "&password=" + password;
    if (type == 1)
    {
        string nick = string.Empty;
        if (string.IsNullOrEmpty(nickname) == false)
            nick = "&nickname=" + nickname;

        url = APIHelper.ApiClient.BaseAddress + "/account/signup.php?username=" + username + "&password=" + password + "&email=" + email + nick;
    }
    if (string.IsNullOrEmpty(url))
        return null;

    using (HttpResponseMessage response = await APIHelper.ApiClient.GetAsync(url).ConfigureAwait(false))
    {
        if (response.IsSuccessStatusCode)
        {
            List<UserModel> listUsers = JsonConvert.DeserializeObject<List<UserModel>>(await response.Content.ReadAsStringAsync().ConfigureAwait(false));

            return listUsers;
        }
        else
            return null;
    }
}

这是不同的async方法之一。当我省略 时ConfigureAwait(false),我遇到了僵局。当我将它添加到代码中时,我遇到了错误。

请你帮助我好吗。

标签: c#xamarinasynchronousxamarin.formsasync-await

解决方案


您可以使用Task.Run( //call your async method here );

所以在你的情况下:

 Task.Run(Startup);

推荐阅读