@@ -130,49 +130,55 @@ module AsyncVal =
130130 /// executed asynchronously, one by one with regard to their order in array.
131131 /// Returned array maintain order of values.
132132 /// If the array contains a Failure, then the entire array will not resolve
133- let collectSequential (values : AsyncVal<'T>[]) : AsyncVal<'T[]> =
134- if values.Length = 0 then Value [||]
135- elif values |> Array.exists isAsync then
133+ let collectSequential (values : AsyncVal<'T> seq) : AsyncVal<'T[]> =
134+ let values = new PooledResizeArray<_> (values)
135+ let length = values.Count
136+ if length = 0 then Value [||]
137+ elif values.Exists isAsync then
136138 Async (async {
137- let results = Array.zeroCreate values.Length
138- let exceptions = ResizeArray values.Length
139- for i = 0 to values.Length - 1 do
139+ let results = Array.zeroCreate length
140+ use exceptions = new PooledResizeArray<_> (length)
141+ for i = 0 to length - 1 do
140142 let v = values.[i]
141143 match v with
142144 | Value v -> results.[i] <- v
143145 | Async a ->
144146 let! r = a
145147 results.[i] <- r
146148 | Failure f -> exceptions.Add f
149+ values.Dispose()
147150 match exceptions.Count with
148151 | 0 -> return results
149152 | 1 -> return exceptions.First().Reraise ()
150- | _ -> return AggregateException exceptions |> raise
153+ | _ -> return AggregateException ( exceptions.AsReadOnly()) |> raise
151154 })
152155 else
153- let exceptions =
156+ use values = values
157+ use exceptions =
154158 values
155- |> Array.choose (function
156- | Failure f -> Some f
157- | _ -> None )
158- match exceptions.Length with
159- | 0 -> Value (values |> Array .map (fun (Value v) -> v))
159+ |> PooledResizeArray.vChoose (function
160+ | Failure f -> ValueSome f
161+ | _ -> ValueNone )
162+ match exceptions.Count with
163+ | 0 -> Value (values |> Seq .map (fun (Value v) -> v) |> Seq.toArray )
160164 | 1 -> Failure (exceptions.First ())
161- | _ -> Failure (AggregateException exceptions)
165+ | _ -> Failure (AggregateException ( exceptions.AsReadOnly()) )
162166
163167 /// Converts array of AsyncVals into AsyncVal with array results.
164168 /// In case when are non-immediate values in provided array, they are
165169 /// executed all in parallel, in unordered fashion. Order of values
166170 /// inside returned array is maintained.
167171 /// If the array contains a Failure, then the entire array will not resolve
168- let collectParallel (values : AsyncVal<'T>[]) : AsyncVal<'T[]> =
169- if values.Length = 0 then Value [||]
172+ let collectParallel (values : AsyncVal<'T> seq) : AsyncVal<'T[]> =
173+ use values = new PooledResizeArray<_> (values)
174+ let length = values.Count
175+ if length = 0 then Value [||]
170176 else
171- let indexes = List <_> (0 )
172- let continuations = List <_> (0 )
173- let results = Array.zeroCreate values.Length
174- let exceptions = ResizeArray values.Length
175- for i = 0 to values.Length - 1 do
177+ let indexes = new PooledResizeArray <_> (length )
178+ let continuations = new PooledResizeArray <_> (length )
179+ let results = Array.zeroCreate length
180+ use exceptions = new PooledResizeArray<_> (length)
181+ for i = 0 to length - 1 do
176182 let value = values.[i]
177183 match value with
178184 | Value v -> results.[i] <- v
@@ -182,13 +188,15 @@ module AsyncVal =
182188 | Failure f -> exceptions.Add f
183189 match exceptions.Count with
184190 | 1 -> AsyncVal.Failure (exceptions.First ())
185- | count when count > 1 -> AsyncVal.Failure (AggregateException exceptions)
191+ | count when count > 1 -> AsyncVal.Failure (AggregateException ( exceptions.AsReadOnly()) )
186192 | _ ->
187193 if indexes.Count = 0 then Value (results)
188194 else Async (async {
189195 let! vals = continuations |> Async.Parallel
190196 for i = 0 to indexes.Count - 1 do
191197 results.[indexes.[i]] <- vals.[i]
198+ indexes.Dispose()
199+ continuations.Dispose()
192200 return results
193201 })
194202
0 commit comments