1

在此处输入图像描述当任务完成时,我需要去下一个活动,但它不会。它成功地在数据库中创建了一个帐户,但不会继续。

如下所示,我已经尝试过 oncomplete(task) 但是一旦我输入凭据并点击注册,它就会创建帐户但不会继续。

下面的代码(使用 refit 进行 Http 请求):

using Kula.API;
using Refit;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;

namespace Kula
{
// Learn more about making custom code visible in the Xamarin.Forms previewer
// by visiting https://aka.ms/xamarinforms-previewer
[DesignTimeVisible(false)]
public partial class MainPage : ContentPage
{
    // set variables 
    Entry RinputEmail;
    Entry RinputPassword;
    Entry RinputUsername;
    Entry RinputFullName;
    IMyAPI myAPI;
    APIRequestHelper apiRequestHelper;
    public MainPage()
    {
        InitializeComponent();

        myAPI = RestService.For<IMyAPI>("http://10.0.2.2:8080");

        apiRequestHelper = new APIRequestHelper(myAPI);
        // reference mainpage.xamal
        RinputEmail = this.FindByName<Entry>("Remail");
        RinputPassword = this.FindByName<Entry>("Rpassword");
        RinputUsername = this.FindByName<Entry>("Rusername");
        RinputFullName = this.FindByName<Entry>("Rfullname");

    }

    async private void GTLogin_Clicked(object sender, EventArgs e)
    {
        //navigate to Login page
        await Navigation.PushAsync(new Login());
    }

    async private void registerUser_Clicked(object sender, EventArgs e)
    {
        await apiRequestHelper.RequestRegisterUserAsync((RinputEmail.Text).ToString(), 
  (RinputPassword.Text).ToString(), (RinputUsername.Text).ToString(), 
  (RinputFullName.Text).ToString()).ContinueWith((nextpage) => { Navigation.PushAsync(new 
  Login()); });


    }



}
};

API_REQUEST_HELPER

   namespace Kula.API
 {
public class APIRequestHelper
{

    IMyAPI myAPI;

    public APIRequestHelper(IMyAPI myAPI)
    {

        this.myAPI = myAPI;
    }

    public async Task RequestRegisterUserAsync(string email, string 
   password, string username, string fullname)
    {


        //create params for request 
        Dictionary<string, object> data = new Dictionary<string, 
   object>();
        data.Add("username", username);
        data.Add("email", email);
        data.Add("password", password);
        data.Add("fullname", fullname);

         await myAPI.RegisterUser(data);






    }

    /*
    public async Task RequestRegisterUserAsync(string email, string 
   password, Boolean returntoken)
    {


        //create params for request 
        Dictionary<string, object> data = new Dictionary<string, 
   object>();
        data.Add("email", email);
        data.Add("password", password);
        data.Add("returnSecureToken", returntoken);


        string result = await myAPI.RegisterUsertwo(data);

    }
    */
    public async Task RequestLoginUserAsync(string email, string 
  password, Boolean returntoken)
    {


        //create params for request 
          Dictionary<string, object> data = new Dictionary<string, 
  object>();
        data.Add("email", email);
        data.Add("password", password);
        data.Add("returnSecureToken", returntoken);


        string result = await myAPI.LoginUser(data);

    }

    public async Task RequestLoginUserAsync(string email, string password)
    {


        //create params for request 
        Dictionary<string, object> data = new Dictionary<string, 
  object>();
        data.Add("email", email);
        data.Add("password", password);



        string result = await myAPI.LoginUser(data);

    }

    public async Task RequestSaveProfileInfoAsync(string username, string fullname)
    {


        //create params for request 
        Dictionary<string, object> data = new Dictionary<string, 
 object>();
        data.Add("username", username);
        data.Add("fullname", fullname);
        string result = await myAPI.SaveProfileInfo(data);

    }
  }
}

MY_API

using Kula.Models;
using Refit;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;

namespace Kula.API
{

public interface IMyAPI
{
    [Get("/Getuid")]
    Task<string> GetUid();

    [Post("/register")]
    Task<string> 
 RegisterUser([Body(BodySerializationMethod.UrlEncoded)] 
  Dictionary<string, object> data);


    [Get("/response")]
    Task<string> GetResponse();

    [Post("/accounts:signInWithPassword?key=")]
    Task<string> LoginUser([Body(BodySerializationMethod.UrlEncoded)] 
   Dictionary<string, object> data);

    [Post("/SaveProfileInfo")]
    Task<string> 
    SaveProfileInfo([Body(BodySerializationMethod.UrlEncoded)] 
    Dictionary<string, object> data);

    [Get("/GetProfileInfo")]
    Task<List<string>> GetProfileInfo();

    [Get("/GetSocialFeedTiles")]
    Task<List<string>> GetSocialFeedTiles();



}
4

2 回答 2

1

因为apiRequestHelper或您的方法RequestRegisterUserAsync返回的内容无法获取主 UI 的句柄,因此您必须使用委托来执行此操作。

   await apiRequestHelper.RequestRegisterUserAsync((RinputEmail.Text).ToString(), 
  (RinputPassword.Text).ToString(), (RinputUsername.Text).ToString(), 
  (RinputFullName.Text).ToString()).ContinueWith(delegate { Navigation.PushAsync(new 
  Login()); });

或者您可以按照上面的答案将代码分开。

await apiRequestHelper.RequestRegisterUserAsync((RinputEmail.Text).ToString(),(RinputPassword.Text).ToString(),(RinputUsername.Text).ToString(),(RinputFullName.Text).ToString());
await Navigation.PushAsync(new Login());
于 2019-11-22T14:11:04.753 回答
1

我用以下简单代码模拟了您的问题:

async private void registerUser_Clicked(object sender, EventArgs e)
{
    await Task.Delay(5000).ContinueWith((x) => Navigation.PushAsync(new Page1()));
}

如果你在与你的行中放置一个断点,Navigation.PushAsync你会注意到它是从一个不是主线程的线程中调用的。这就是为什么即使代码到达那部分,它也没有任何效果:您只能从主线程更改 UI !

要实现这一点,您可以简单地以常规方式使用 async await,如下所示:

async private void registerUser_Clicked(object sender, EventArgs e)
{
    await Task.Delay(5000);
    await Navigation.PushAsync(new Page1());
}

或者回到你自己的代码:

async private void registerUser_Clicked(object sender, EventArgs e)
{
    await apiRequestHelper.RequestRegisterUserAsync((RinputEmail.Text).ToString(),(RinputPassword.Text).ToString(), (RinputUsername.Text).ToString(),(RinputFullName.Text).ToString());

    await Navigation.PushAsync(new Login());
}

可以在此处找到有关 async/await + Xamarin.Forms 的好帖子:

https://devblogs.microsoft.com/xamarin/getting-started-with-async-await/


奖金:

您提到使用OnComplete:使用它来让您的EventHandler启动登录页面的一种方法是将任务配置为返回到主线程,方法是使用ConfigureAwait

Task.Delay(5000).ConfigureAwait(true).GetAwaiter().OnCompleted(()=>Navigation.PushAsync(new Page1()));

注意 ConfigureAwait( true ) 的使用,如果您使用 ConfigureAwait( false ),则该PushAsync方法再次从主线程以外的线程调用!

于 2019-11-22T21:19:14.697 回答