roubachof / Sharpnado.CollectionView

A performant list view supporting: grid, horizontal and vertical layout, drag and drop, and reveal animations.
The Unlicense
244 stars 30 forks source link

Fixed UI Thread desynchrony when modifying ItemSource #81

Closed ems107 closed 8 months ago

ems107 commented 1 year ago
using var h = new Handler(Looper.MainLooper);
h.Post(
    () =>
    {
        // Code executed on UI Thread
    });

By using this code, you are passing an action to the main thread, enqueued, and it will be executed when the main thread finishes all the tasks ahead of it.

If I'm not wrong, this is exactly the same as using Device.BeginInvokeOnMainThread from Xamarin.Forms.

I have replaced the code with the Xamarin.Essentials implementation of MainThread.BeginInvokeOnMainThread. (Note: Device.BeginInvokeOnMainThread and MainThread.BeginInvokeOnMainThread do not work exactly the same: https://github.com/xamarin/Essentials/issues/1070)

Device.BeginInvokeOnMainThread always enqueues the Action (like the code does right now). MainThread.BeginInvokeOnMainThread first checks if the current thread is the interface thread, in which case the Action is executed directly. If the current thread is not the interface thread, then it has the same behavior as Device.BeginInvokeOnMainThread.

In our specific case, since it was not executed directly if it was in the interface thread, it caused us a synchrony error. We were modifying the list by adding a new item (being in the interface thread) and then we wanted to scroll to this new item. Since the method that adds the new item to the internal list is in the execution queue, the scroll was executing before the item itself was added internally.

roubachof commented 1 year ago

will be fixed in maui version