まず、loginButtonGesture_Tapped()イベントハンドラはUIスレッドによってトリガされるため、Device.BeginInvokeOnMainThread()を使用する必要はありません。すでにUIスレッド内にあります。しかし、ここでDevice.BeginInvokeOnMainThread()を使用して以来、遅延の理由は、AndroidではBeginInvokeOnMainThread()内のコードがMainLooperのメッセージキューに追加され(コードはすぐに実行されません)、UIスレッドそのメッセージを処理する予定です。 iOS用
:
はXamarinのドキュメントで見つけることができる詳細な回答
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スレッドで指定されたセレクタで公開されている指定されたオブジェクトのコードを呼び出します。 これは、どちらのAPIもスレッドセーフではないため、UIKitまたはAppKitに影響するほとんどの操作に必要です。
メインスレッドがイベントを処理するためにメインループに戻るときにコードが実行されます。 Android用
:
多くの人が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(アクション)によってすぐに実行されません。これは、ルーパーのメッセージキューに追加され、UIスレッドがそのメッセージを処理するようにスケジュールされているときに処理されます。