AvaloniaUtils/AsyncImageLoader.Avalonia

AdvancedImage.UpdateImage can error with "CancellationTokenSource has been disposed" when redrawn rapidly in virtualizing panels

ionite34 opened this issue · 2 comments

In a virtualizing ItemsRepeater, when scrolling back and forth rapidly and causing redraws, the AdvancedImage.UpdateImage method can error with ObjectDisposedException likely due to the previous call not finishing before the new call, perhaps a lock mechanism is needed?

Relevant lines:
https://github.com/AvaloniaUtils/AsyncImageLoader.Avalonia/blob/830e2bfd0ee30e85f81821d8636e4ed59a1084fd/AsyncImageLoader.Avalonia/AdvancedImage.axaml.cs#L189C3-L189C10

Hello, @ionite34

Just pushed an 3.2.1-rc1 version with some changes, related to this problem. Can you check out, does it solves your problem?

Hello, @ionite34

Just pushed an 3.2.1-rc1 version with some changes, related to this problem. Can you check out, does it solves your problem?

This seems to still occur but errors on a different line, ObjectDisposedException when accessing .Token

await Task.Delay(10, cancellationTokenSource.Token);

I think the cause is that another call of UpdateImage, despite the interlocked exchange, can get the var cancellationTokenSource = new CancellationTokenSource(); and disposes it before the cancellationTokenSource.Token access which errors.

I reproduced the error in the demo project by modifying this function in AdvancedImagePage to do a lot of Source changes

        private void SetSourceButton_OnClick(object? sender, RoutedEventArgs e)
        {
            Task.Run(() =>
            {
                Parallel.ForEach(Enumerable.Range(0, 100), i =>
                {
                    Dispatcher.UIThread.Invoke(() =>
                    {
                        CurrentImageExample.Source = $"/Assets/cat{Random.Shared.Next(4, 6)}.jpg";
                    });
                });
            });
        }

I've linked #20 which seems to fix the issue