ui kit一致性错误出错

rog*_*nin 3 c# xamarin.ios xamarin

我在访问视图控制器.cs文件中的文本框时遇到问题

 async partial void loginUser(UIButton sender)

{

    // Show the progressBar as the MainActivity is being loade


    Console.WriteLine("Entered email : " + txtEmail.Text);


        // Create user object from entered email
        mCurrentUser = mJsonHandler.DeserialiseUser(txtEmail.Text);
        try
        {

            Console.WriteLine("Starting network check");
            // Calls email check to see if a registered email address has been entered
            if (EmailCheck(txtEmail.Text) == true)
            {
                await  CheckPassword();
            }
            else
            {
                UIAlertView alert = new UIAlertView()
                {
                    Title = "Login Alert",
                    Message = "Incorrect email or password entered"
                };
                alert.AddButton("OK");
                alert.Show();

            }


        }
        catch (Exception ex)
        {
            System.Diagnostics.Debug.WriteLine("An error has occured: '{0}'", ex);
        }
Run Code Online (Sandbox Code Playgroud)

正是在这个功能范围内,它抱怨它无法访问aynsc方法上的文本框

    public Task CheckPassword()
    {

   return Task.Run(() =>
    {
            // Creates instance of password hash to compare plain text and encrypted passwords.
            PasswordHash hash = new PasswordHash();
            // Checks password with registered user password to confirm access to account.
            if (hash.ValidatePassword(txtPassword.Text ,mCurrentUser.password)==true)
            {
                Console.WriteLine("Password correct");


                UIAlertView alert = new UIAlertView()
                {
                    Title = "Login Alert",
                    Message = "Password Correct Loggin In"
                };
                alert.AddButton("OK");
                alert.Show();
                //insert intent call to successful login here.

            }
            else
            {
                UIAlertView alert = new UIAlertView()
                {
                    Title = "Login Alert",
                    Message = "Incorrect email or password entered"
                };
                alert.AddButton("OK");
                alert.Show();

            }
            Console.WriteLine("Finished check password");
        });
    }
Run Code Online (Sandbox Code Playgroud)

它的这一行发生错误:

txtPassword.Text 
Run Code Online (Sandbox Code Playgroud)

错误如下:

UIKit.UIKitThreadAccessException:UIKit一致性错误:您正在调用只能从UI线程调用的UIKit方法.

即使密码正确,我的密码修正也不会显示.我是否必须在单独的线程上运行UI警报?

小智 17

必须从UI线程(或主线程,主队列等)调用任何UIKit方法.这确保了UI的一致性.Xamarin在调试模式下为所有UIKit方法添加了一个检查,如果您尝试使用后台线程来更改UI,则会抛出该异常.

解决方案很简单:只从UI线程修改UI.这实际上意味着如果你在前面使用带有"UI"的类,你应该从UI线程中做到这一点.(这是一个经验法则,还有其他时间在UI线程上).

如何在这个神秘的UI线程上获取我的代码?我很高兴你问.在iOS中,您有几个选择:

  • 当在NSObject的子类中时,InvokeOnMainThread会做到这一点.
  • 从任何地方,CoreFoundation.DispatchQueue.MainQueue.DispatchAsync将永远工作.

这两种方法都只接受一个Action,可以是lambda或方法.

所以在你的代码中,如果我们添加一个InvokeOnMainThread(因为我认为这是在你的UIViewController子类中)...

 public Task CheckPassword()
 {

     return Task.Run(() =>
     {
        // Creates instance of password hash to compare plain text and encrypted passwords.
        PasswordHash hash = new PasswordHash();
        // Checks password with registered user password to confirm access to account.
        InvokeOnMainThread(() => {
            if (hash.ValidatePassword(txtPassword.Text ,mCurrentUser.password)==true)
            {
                Console.WriteLine("Password correct");


                UIAlertView alert = new UIAlertView()
                {
                    Title = "Login Alert",
                    Message = "Password Correct Loggin In"
                };
                alert.AddButton("OK");
                alert.Show();
                //insert intent call to successful login here.

            }
            else
            {
                UIAlertView alert = new UIAlertView()
                {
                    Title = "Login Alert",
                    Message = "Incorrect email or password entered"
                };
                alert.AddButton("OK");
                alert.Show();

            }
        });
        Console.WriteLine("Finished check password");
    });
}
Run Code Online (Sandbox Code Playgroud)