The simple answer: The background thread cannot change the interface elements, because most of the user interface operations in iOS and Android are not thread safe; therefore, you need to call the user interface thread to execute code that modifies the user interface, such as MyLabel.Text = "New Text".
A detailed answer can be found in the Xamarin document:
For iOS:
IOSPlatformServices.BeginInvokeOnMainThread () The method simply calls 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/
This method is used from the stream to call code in the specified object, which is displayed with the specified selector in the user interface stream. This is required for most operations that affect UIKit or AppKit, since none of these APIs is thread safe.
Code is executed when the main thread returns to its main loop to handle events.
For Android:
Many people think that the Xamarin.Android BeginInvokeOnMainThread () method uses Activity.runOnUiThread (), BUT this is not the case, and there is a difference between using runOnUiThread () and Handler.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. } }
The actual implementation of the Xamarin.Android BeginInvokeOnMainThread () method can be found in the AndroidPlatformServices.cs class
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) As you can see, the action code is not immediately executed by the Handler.Post (action) handler. It is added to the Looper message queue and processed when the user interface thread is scheduled to process its message.
chris hu
source share