Skip to content

Race condition with SetIsLoading on Windows #71

@craigwi

Description

@craigwi

I hit a race condition during startup on Windows which can result in the following exception:

System.ArgumentException: An item with the same key has already been added. Key: Microsoft.Maui.Controls.BindableProperty
at System.Collections.Generic.Dictionary2.TryInsert(TKey key, TValue value, InsertionBehavior behavior) at System.Collections.Generic.Dictionary2.Add(TKey key, TValue value)
at Microsoft.Maui.Controls.BindableObject.SetValueCore(BindableProperty property, Object value, SetValueFlags attributes, SetValuePrivateFlags privateAttributes, SetterSpecificity specificity)
at Microsoft.Maui.Controls.BindableObject.SetValue(BindablePropertyKey propertyKey, Object value)
at FFImageLoading.Maui.CachedImage.SetIsLoading(Boolean isLoading)
at FFImageLoading.Maui.Platform.CachedImageHandler.UpdateImage(Image imageView, CachedImage image, CachedImage previousImage)
at System.Threading.Tasks.Task.<>c.b__128_0(Object state)
at Microsoft.UI.Dispatching.DispatcherQueueSynchronizationContext.<>c__DisplayClass2_0.b__0()

This appears to be due to two threads trying to add the IsLoading property at the same time. I thought it was the MainThreadDispatcher which gets the Dispatcher based on the current thread, not specifically the main thread. I created a private version of MainThreadDispatcher which always used Application.Current.Dispatcher, but that did not help.

Given the core issue of two threads adding the same property to the dictionary, I tried to force that property entry to be added. That seems to work.

Specifically, I created this:

public class CachedImage2 : CachedImage
{
    public CachedImage2()
    {
        // preset so as not to hit a race condition later
        this.SetIsLoading(false);
    }
}

and then always used CachedImage2.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions