none
ImmutableArray<T>.Add(..) throws exception when called concurrently from multiple threads RRS feed

  • Question

  • I played around with ImmutableArray<T> from NuGet package System.Collections.Immutable (version 1.1.32-beta) and found an unexpected behavior. Not sure if I'm doing something wrong.

    Suppose, I have following simple publisher that uses an ImmutableArray<String> to hold an internal list of subscriptions (in that sample subscriptions are just strings).

    public class SamplePublisher
    {
        private ImmutableArray<String> mSubscriptions = ImmutableArray<String>.Empty;
    
    
        public void Subscribe(String key)
        {
            ImmutableInterlocked.InterlockedExchange(
                ref mSubscriptions, 
                mSubscriptions.Add(key));
        }
    }

    Now, when I call Subscribe() (which calls Add on the immutable array) concurrently from multiple threads I get an unexpected exception. I though those collections were thread-safe?!

    var publisher = new SamplePublisher();
    
    Action<SamplePublisher> action = (_publisher) =>
        {
            for (Int32 i = 0; i < 100000; i++)
    	    _publisher.Subscribe(i.ToString());
        };
    
    var task1 = Task.Run(() => action(publisher));
    var task2 = Task.Run(() => action(publisher));
    
    Task.WaitAll(task1, task2);


    Here are exception details:

    System.ArgumentException : Source array was not long enough. Check srcIndex and length, and the array's lower bounds. at System.Array.Copy(Array sourceArray, Int32 sourceIndex, Array destinationArray, Int32 destinationIndex, Int32 length, Boolean reliable) at System.Array.Copy(Array sourceArray, Int32 sourceIndex, Array destinationArray, Int32 destinationIndex, Int32 length) at System.Collections.Immutable.ImmutableArray`1.Insert(Int32 index, T item) at System.Collections.Immutable.ImmutableArray`1.Add(T item) ...

    As a side note, yes I know that ImmutableArray<T> is intended for scenarios where your collection is rarely modified. Nevertheless the ArgumentException thrown from within Insert(..) shouldn't happen, right?

    Is that a possible bug in the implementation?

    Am I doing something wrong here? Using ImmutableArray<T> in an unexpected way?



    • Edited by Olaf-Kober Thursday, December 4, 2014 9:29 PM fixed typo in code
    Thursday, December 4, 2014 8:18 AM

Answers

  • Ah, the NuGet package was renamed recently by Microsoft, from Microsoft.Bcl.Immutable to System.Collections.Immutable, whereas Microsoft.Bcl.Immutable was marked as deprecated. The announcement can be read here: http://blogs.msdn.com/b/bclteam/p/immutable.aspx.

    In the meantime, I reported the issue on GitHub dotnet/corefx (https://github.com/dotnet/corefx/issues/191) and it has already been fixed.

    Thanks
    Olaf

    • Marked as answer by Olaf-Kober Tuesday, December 9, 2014 7:10 AM
    Tuesday, December 9, 2014 7:10 AM

All replies

  • Hello Olaf-Kober,

    >>Is that a possible bug in the implementation?Am I doing something wrong here? Using ImmutableArray<T> in an unexpected way?

    According to your description, I installed the version 1.1.32-beta and reproduce this issue successfully, while I notice that in the download link there is a warning which shows:

    Since this is a beta version and is not unlisted in the stable download page, it should not be used as it recommends. I suggest that you could use the ImmutableList<T> Class instead. When the team releases a stable one, you could download it and use it.

    Regards.


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    Friday, December 5, 2014 7:13 AM
    Moderator
  • Hi Fred!

    Thank's for your response!

    I know that this is a pre-release version, but I didn't realized that the package was unlisted. Where did you read this? NuGet shows me the pre-release warning but nothing about a deprecated package...

    In the meantime, I found out that immutable collections are part of open-sourced .NET Core. The version over there shows the same behavior. I will further discuss the issue there.

    Kind regards,
    Olaf

    Friday, December 5, 2014 6:46 PM
  • Hello Olaf-Kober,

    Since I original do not find the version 1.1.32-beta link, I only find the version 1.1.22-beta, so I change the version number to 1.1.32 and it returns the below link:

    http://www.nuget.org/packages/Microsoft.Bcl.Immutable/1.1.32-beta.

    Not sure why there are two different sites pointing to same thing.

    If you consider it to be a bug, you could post this feedback to:

    https://connect.microsoft.com/VisualStudio

    Regards.


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    Monday, December 8, 2014 9:39 AM
    Moderator
  • Ah, the NuGet package was renamed recently by Microsoft, from Microsoft.Bcl.Immutable to System.Collections.Immutable, whereas Microsoft.Bcl.Immutable was marked as deprecated. The announcement can be read here: http://blogs.msdn.com/b/bclteam/p/immutable.aspx.

    In the meantime, I reported the issue on GitHub dotnet/corefx (https://github.com/dotnet/corefx/issues/191) and it has already been fixed.

    Thanks
    Olaf

    • Marked as answer by Olaf-Kober Tuesday, December 9, 2014 7:10 AM
    Tuesday, December 9, 2014 7:10 AM