首先,loginButtonGesture_Tapped()事件处理程序由UI线程触发,因此您不需要使用Device.BeginInvokeOnMainThread(),它已经在UI线程中。但是由于您在这里使用了Device.BeginInvokeOnMainThread(),所以延迟的原因是因为在Android上,BeginInvokeOnMainThread()中的代码被添加到MainLooper的消息队列中(您的代码不会立即执行)并在UI线程计划处理其消息。
详细的答案可以Xamarin的文件中找到:
对于iOS:
IOSPlatformServices.BeginInvokeOnMainThread()方法简单地调用NSRunLoop.Main.BeginInvokeOnMainThread
public void BeginInvokeOnMainThread(Action action)
{
NSRunLoop.Main.BeginInvokeOnMainThread(action.Invoke);
}
https://developer.xamarin.com/api/member/Foundation.NSObject.BeginInvokeOnMainThread/p/ObjCRuntime.Selector/Foundation.NSObject/
您可以使用此方法从线程调用UI线程中指定的选择器公开的指定对象中的代码。 这对大多数影响UIKit或AppKit的操作都是必需的,因为这些API中的任何一个都不是线程安全的。
代码在主线程返回主循环处理事件时执行。
对于安卓
很多人总以为上Xamarin.Android BeginInvokeOnMainThread()方法配合使用Activity.runOnUiThread(),但这种情况并非如此,并没有使用runOnUiThread()和处理器之间的差异.POST():
public final void runOnUiThread(Runnable action) {
if (Thread.currentThread() != mUiThread) {
mHandler.post(action);//<-- post message delays action until UI thread is scheduled to handle messages
} else {
action.run();//<--action is executed immediately if current running thread is UI thread.
}
}
实际实现Xamarin.Android BeginInvokeOnMainThread()的方法可以在AndroidPlatformServices.cs类中找到
public void BeginInvokeOnMainThread(Action action)
{
if (s_handler == null || s_handler.Looper != Looper.MainLooper)
{
s_handler = new Handler(Looper.MainLooper);
}
s_handler.Post(action);
}
https://developer.android.com/reference/android/os/Handler.html#post(java.lang.Runnable) 正如您所看到的,您的操作代码不会立即由Handler.Post(action)执行。它被添加到Looper的消息队列中,并在UI线程计划处理其消息时进行处理。