Przeglądaj źródła

Optimize ToList.

Bart De Smet 7 lat temu
rodzic
commit
8a22b4d819

+ 26 - 8
Ix.NET/Source/System.Linq.Async/System/Linq/Operators/ToList.cs

@@ -15,7 +15,7 @@ namespace System.Linq
             if (source == null)
                 throw new ArgumentNullException(nameof(source));
 
-            return ToList(source, CancellationToken.None);
+            return ToListCore(source, CancellationToken.None);
         }
 
         public static Task<List<TSource>> ToList<TSource>(this IAsyncEnumerable<TSource> source, CancellationToken cancellationToken)
@@ -23,18 +23,36 @@ namespace System.Linq
             if (source == null)
                 throw new ArgumentNullException(nameof(source));
 
+            return ToListCore(source, cancellationToken);
+        }
+
+        private static Task<List<TSource>> ToListCore<TSource>(IAsyncEnumerable<TSource> source, CancellationToken cancellationToken)
+        {
             if (source is IAsyncIListProvider<TSource> listProvider)
                 return listProvider.ToListAsync(cancellationToken);
 
-            return source.Aggregate(
-                new List<TSource>(),
-                (list, x) =>
+            return Core();
+
+            async Task<List<TSource>> Core()
+            {
+                var e = source.GetAsyncEnumerator(cancellationToken);
+
+                try
                 {
-                    list.Add(x);
+                    var list = new List<TSource>();
+
+                    while (await e.MoveNextAsync().ConfigureAwait(false))
+                    {
+                        list.Add(e.Current);
+                    }
+
                     return list;
-                },
-                cancellationToken
-            );
+                }
+                finally
+                {
+                    await e.DisposeAsync().ConfigureAwait(false);
+                }
+            }
         }
     }
 }