Skip to content

Problem of having intermittent exception of ArgumentException when adding item in List<T> wrapped in Task.WhenAll #116402

Closed as not planned
@eriawan

Description

@eriawan

Description

I am trying to test some codes/logics that basically testing the speed or perf of adding item to a List and then this code is wrapped inside a Task.Run, then the code in the Task.Run is awaited, added to a List, and then all of the tasks are awaited into a single Task.WhenAll.

Unfortunately I got exceptions intermittently thrown when adding item to a List.

Reproduction Steps

This is the code to reproduce on my gist at GitHub:
https://gist.github.com/eriawan/65d38acbdd3649f394d6eff0f1faa434

Just run the console project and the code files in that Gist.

This method is excerpted from the Gist, note the line that add the item to randomResult, this is the point that throws exception.

        public static async Task TaskWhenAll_ProcessIterateFor()
        {
            List<Task> tasklist = new List<Task>();
            List<Double> randomResult = new List<Double>();
            for (int i = 1; i <= 50; i++)
            {
                tasklist.Add(Task.Run(() =>
                {
                    var iterationResult = ProcessIterateFor(60);
                    iterationResult.ForEach((resultItem) => randomResult.Add(resultItem));
                }));
            }
            await Task.WhenAll(tasklist);
        }

Expected behavior

I expect that it should not be having/throwing error/exception at all.

Actual behavior

This exception is intermittently thrown:

  • Type: System.ArgumentException
  • Exceptio message: Source array was not long enough. Check the source index, length, and the array's lower bounds. (Parameter 'sourceArray')
  • Stack trace: (with "Just my code" setting disabled)
   at System.Array.CopyImpl(Array sourceArray, Int32 sourceIndex, Array destinationArray, Int32 destinationIndex, Int32 length, Boolean reliable) in /_/src/coreclr/System.Private.CoreLib/src/System/Array.CoreCLR.cs:line 45
   at System.Collections.Generic.List`1.set_Capacity(Int32 value) in /_/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/List.cs:line 114
   at System.Collections.Generic.List`1.AddWithResize(T item) in /_/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/List.cs:line 218
   at DiskusiTestArrayExceptionDiTaskWhenAll.MiscelanousComputeProcessSimplified.<>c__DisplayClass1_0.<TaskWhenAll_ProcessIterateFor>b__1(Double resultItem) in D:\github-repo-large\belajar-dotnet-bahasa\source\DiskusiTestArrayExceptionDiTaskWhenAll\MiscelanousComputeProcessSimplified.cs:line 35
   at System.Collections.Generic.List`1.ForEach(Action`1 action) in /_/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/List.cs:line 616
   at DiskusiTestArrayExceptionDiTaskWhenAll.MiscelanousComputeProcessSimplified.<>c__DisplayClass1_0.<TaskWhenAll_ProcessIterateFor>b__0() in D:\github-repo-large\belajar-dotnet-bahasa\source\DiskusiTestArrayExceptionDiTaskWhenAll\MiscelanousComputeProcessSimplified.cs:line 35
   at System.Threading.ExecutionContext.RunFromThreadPoolDispatchLoop(Thread threadPoolThread, ExecutionContext executionContext, ContextCallback callback, Object state) in /_/src/libraries/System.Private.CoreLib/src/System/Threading/ExecutionContext.cs:line 264
--- End of stack trace from previous location ---

Screenshots:

Sample console output:
Image

When exception caught:

Image

and this is the debugged source code of that:

Image

Regression?

Not that I can tell whether this is regression or not, but I can reproduce this on .NET Framework 4.8, .NET 8.0 and .NET 9.0, although the stack trace is for .NET 8.0 and .NET 9.0

Known Workarounds

If I use ConcurrentBag within the code that add the item, the problem seems almost gone, although the perf is somehow slower.
But is this the only way? Just for curiosity, I have tried to use lock, CMIIW. But using lock still doesn't solve the problem and the perf is worse than without lock.

Any correction/feedback appreciated, thanks in advance!

Configuration

.NET SDK I use:

  1. .NET SDK 9.0.300, Runtime: 9.0.5
  2. .NET SDK 8.0.410, Runtime 8.0.16
    Visual Studio used: VS 2022 17.14.4

Other information

If I use Parallel.ForAsync, the problem is gone. But I may have less scenario to test, as I only have 50 times of loop.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions