Does the ViewModel property set the thread merge property in Xamarin Forms?

The other day, in a code review, I saw several questions about the security of setting properties from a workflow. The collector made a comment: "This property is associated with the user interface, and data binding is thread-safe."

I have been using XF for a while, but have always assumed that this is not the case: if I want to update the ViewModel properties associated with the user interface, I will have to make these changes to the user interface stream. I just spent a few minutes getting through the documentation, and I don't see the obvious answer, except that directly manipulating BindableProperties has thread similarity. It also matters to me if this is a blocking execution of the user interface or not.

I could make a project to test it myself, but such problems always seem intermittent, so I would like to know that I just lack the right documentation.

(This refers to the investigation of the failure, which we see that occurs mainly in the Xamarin call tables. We raise an event from the workflow, the VM processes this event and updates some properties. If this is planned for the user interface thread, there may be some rotation problems which we haven’t prepared, and I’m much closer to solving the problem. If this is not planned for the UI thread ... I am surprised that it worked for so long.)

+5
source share
2 answers

I have been using XF for a while, but have always assumed that this is not the case: if I want to update the ViewModel properties associated with the user interface, I will have to make these changes to the user interface stream.

You're right. 100% right. You can use Device.InvokeOnMainThread() for this.

To be complete, there is one case where it does not matter: PropertyChanged

https://github.com/xamarin/Xamarin.Forms/blob/b645064/Xamarin.Forms.Core/BindingExpression.cs#L542

In this case, Binding is applied to the main (UI) thread.

+1
source

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.

0
source

Source: https://habr.com/ru/post/1257660/


All Articles