Assumptions
We interact with the user interface exclusively through binding. So only setters and getters play.
Getters
The code provided in github by @Stephane only means that your associated getter (s) will be called in the user interface thread. More no less.
Btw, I wouldn’t rely on the source code (I mean: implementation), instead, the specification matters. The implementation may change at any time, and if the specification does not require this, then unit tests will not test this, so there will be a big surprise ...
Incubation
However, it is still unclear whether you can name your setter in the background thread. Regardless of the answer “yes” or “no”, this implies further tasks for the solution.
a) If you can call setters in any thread: this means that your internal viewmodel data is subject to race conditions because they will be called from the user interface thread and you will access them in the background thread. Conclusion: you must protect the data using regular concurrency templates or use classes protected by threads, plus: your getter and setter must be atomic.
b) If it turns out that you cannot call setters in any thread: then you should use Device.InvokeOnMainThread() . But this is only half the story. In the methods of your background thread, you modify the example instance of List. This will be available in the UI thread by the recipient, and you change it in the background thread at the same time when you say that it fills it. Theoretically, the user can interact with the user interface during the population period, which allows you to evaluate the binding, getter.
Conclusions:
If multiple threads access the same data, you should always block the data.
Regardless of what the current source code implies, the safest way to route the getter and setter to the user interface stream. This will not cause significant overhead: if execution is already in progress in the user interface thread, the marshall will do nothing.
Note. Even if you marshall both receivers and setters in the user interface stream, you will access data in the background stream to provide protection against race conditions or to use classes protected by streams.