@@ -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