2013-04-05 14 views
8

Supponendo che ho queste due funzioni:F # utilizzando Async.Parallel per eseguire compiti in parallelo 2

let dowork n = 
    async { 
     do printfn "work %d" n 
    } 

let work i = async { 
    do! Async.Sleep(2000) 
    printfn "work finished %d" i } 

Come dovrei usare Async.Parallel per eseguirli contemporaneamente e attendere che sia di finire prima di procedere?

+0

possibili dups, http://stackoverflow.com/questions/5693279/combining-f- async-functions, http://stackoverflow.com/questions/4106846/how-to-wait-for-async-to-finish – gradbot

risposta

12

Async.Parallel prende una sequenza di asincroni. In questo caso gli passo una lista.

[dowork 1; work 2] 
|> Async.Parallel 
|> Async.RunSynchronously 
|> ignore 

Se si desidera restituire diversi tipi di dati utilizzare un Discriminated Union.

type WorkResults = 
    | DoWork of int 
    | Work of float32 

let dowork n = 
    async { 
     do printfn "work %d" n 
     return DoWork(n) 
    } 

let work i = async { 
    do! Async.Sleep(2000) 
    printfn "work finished %d" i 
    return Work(float32 i/4.0f) 
} 

[dowork 1; work 2] 
|> Async.Parallel 
|> Async.RunSynchronously 
|> printf "%A" 

uscita

work 1 
work finished 2 
[|DoWork 1; Work 0.5f|] 
18

Come accennato in precedenza, basta mettere le funzioni asincrone in una sequenza e li passa alla Async.Parallel.

Ma, se è necessario eseguire diversi lavori che restituiscono i risultati di diversi tipi, è possibile utilizzare Async.StartChild:

let fn1 = async { 
     do! Async.Sleep 1000 
     printfn "fn1 finished!" 
     return 5 
    } 

let fn2 = async { 
     do! Async.Sleep 1500 
     printfn "fn2 finished!" 
     return "a string" 
    } 

let fncombined = async { 
     // start both computations simultaneously 
     let! fn1 = Async.StartChild fn1 
     let! fn2 = Async.StartChild fn2 

     // retrieve results 
     let! result1 = fn1 
     let! result2 = fn2 

     return sprintf "%d, %s" (result1 + 5) (result2.ToUpper()) 
    } 

fncombined 
|> Async.RunSynchronously 
|> printfn "%A" 
+2

Non mi interessa se la tua non è la risposta selezionata, per me, tu sei il real mvp –

+2

Sono d'accordo, ho cercato di capire come fare questo e questo esempio è ESATTAMENTE quello che stavo cercando! – Keith

Problemi correlati