One section in excellent article "Patterns of Parallel Programming" is dedicated to idiom "Speculative processing". In brief we can start multiple computation in parallel (utilizing advantages of multiple cores), take first result and ignore others. Unfortunatly F# library doesn't provide builtin primitive for this strategy. Code below contains sketch of possible solution.
open System.Threading
type Async with
static member Any(asyncs : seq<Async<'T>>) =
let value = ref false
let cts = new CancellationTokenSource()
Async.FromContinuations(fun (cont, econt, ccont) ->
// accepts result value only once, subsequent calls will be ignored
let kont v =
do lock value (fun () ->
match !value with
| true -> ()
| false ->
value := true
cts.Cancel()
cont v
)
// runs specified computation in new thread
let wrapper a = async {
do! Async.SwitchToNewThread()
return! a
}
for a in asyncs do
Async.StartWithContinuations(wrapper a, kont, econt, ignore, cancellationToken = cts.Token)
)
We wrap specified asyncs so they will be started in threadpool threads. After first successful completion result is passed to awaiting continuation and cancellation is signalled. Subsequent results (if any occured) will be ignored.
Update: post with corrected version
Комментариев нет:
Отправить комментарий