首先,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線程計劃處理其消息時進行處理。