Skip to content

Race condition when calling ToArray() on a ConcurrentDictionary #1039

@oSumAtrIX

Description

@oSumAtrIX

Describe the bug/issue

Unhandled exception due to System.ArgumentException being thrown when calling .ToArray() on a ConcurrentDictionary object:

foreach (var key in Data.OrderBy(x => x.Value.usage).Take(Data.Count - MaxCached).Select(x => x.Key).ToArray())

References that could help pinpoint the issue:

  1. Lasse V. Karlsen's answer on StackOverflow

Solution proposal:
Either lock access when calling .ToArray() or revert the responsible line from commit a083528:

- foreach (var key in Data.OrderBy(x => x.Value.usage).Take(Data.Count - MaxCached).Select(x => x.Key).ToArray())
+ foreach (var key in Data.OrderBy(x => x.Value.usage).Take(Data.Count - MaxCached).Select(x => x.Key))

Your System

Flow Launcher version: 1.9.2

Flow Launcher Error Log

System.ArgumentException: The index is equal to or greater than the length of the array, or the number of elements in the dictionary is greater than the available space from index to the end of the destination array.
   Source: System.Collections.Concurrent
   TargetAssembly: System.Collections.Concurrent, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
   TargetModule: System.Collections.Concurrent.dll
   TargetSite: Void System.Collections.Generic.ICollection<System.Collections.Generic.KeyValuePair<TKey,TValue>>.CopyTo(System.Collections.Generic.KeyValuePair`2[TKey,TValue][], Int32)
   at System.Collections.Concurrent.ConcurrentDictionary`2.System.Collections.Generic.ICollection<System.Collections.Generic.KeyValuePair<TKey,TValue>>.CopyTo(KeyValuePair`2[] array, Int32 index)
   at System.Collections.Generic.EnumerableHelpers.ToArray[T](IEnumerable`1 source, Int32& length)
   at System.Linq.Buffer`1..ctor(IEnumerable`1 source)
   at System.Linq.OrderedEnumerable`1.GetEnumerator(Int32 minIdx, Int32 maxIdx)+MoveNext()
   at System.Linq.Enumerable.SelectIPartitionIterator`2.PreallocatingToArray(Int32 count)
   at System.Linq.Enumerable.SelectIPartitionIterator`2.ToArray()
   at Flow.Launcher.Infrastructure.Image.ImageCache.<>c__DisplayClass10_0.<<set_Item>g__SliceExtra|1>d.MoveNext() in C:\projects\flow-launcher\Flow.Launcher.Infrastructure\Image\ImageCache.cs:line 77
--- End of stack trace from previous location ---
   at System.Threading.Tasks.Task.<>c.<ThrowAsync>b__140_1(Object state)
   at System.Threading.QueueUserWorkItemCallback.<>c.<.cctor>b__6_0(QueueUserWorkItemCallback quwi)
   at System.Threading.ExecutionContext.RunForThreadPoolUnsafe[TState](ExecutionContext executionContext, Action`1 callback, TState& state)
   at System.Threading.QueueUserWorkItemCallback.Execute()
   at System.Threading.ThreadPoolWorkQueue.Dispatch()

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions