2014-06-16 13 views
6

I risultati dell'operazione Async.Parallel di F # sono garantiti per arrivare nell'ordine in cui sono stati inoltrati i lavori? Il mio codice di esempio restituisce i risultati in ordine, ma non riesco a trovare alcuna menzione nei documenti MSDN o nella specifica F #, assicurando che questo deve essere il - che non è una coincidenza.I risultati F # Async.Parallel sono garantiti in ordine?

Ecco il mio codice di esempio:

let r = System.Random() 
Async.Parallel [ 
    for i in 0..10 -> 
     async { 
      let rand_num = r.Next(10) 
      do! Async.Sleep(rand_num) (* Simulate jobs taking a variable amount of time *) 
      printfn "%i %i" i rand_num 
      return i 
     } 
] 
|> Async.RunSynchronously 
|> printfn "%A" 

Ed ecco l'output.

0 0 
5 1 
4 1 
3 3 
10 6 
9 4 
7 5 
2 5 
1 5 
8 7 
6 9 
[|0; 1; 2; 3; 4; 5; 6; 7; 8; 9; 10|] 

Si può vedere che, in questo periodo, le funzioni asincrone complete al fine indeterminata, eppure la matrice risultante è ordinato. Questo comportamento è garantito?

risposta

11

Al momento, la fonte della funzione è scritta in modo che questa garanzia sia applicata. Guardando control.fs around line #1300 per la definizione, possiamo vedere la funzione che mette i risultati nella matrice di uscita è

let recordSuccess i res = 
    results.[i] <- res; 
    finishTask(Interlocked.Decrement count) 

questa funzione viene chiamata in questo segmento

tasks |> Array.iteri (fun i p -> 
    queueAsync 
     innerCTS.Token 
     // on success, record the result 
     (fun res -> recordSuccess i res) 

dove tasks ha i compiti originali ordinato ordine. Ciò garantisce che l'elenco di output sia nello stesso ordine dell'input.

UPDATE

La specifica almeno sembra implicare che l'ordine è fisso - contiene questo codice:

let rec fib x = if x < 2 then 1 else fib(x-1) + fib(x-2) 

let fibs = 
    Async.Parallel [ for i in 0..40 -> async { return fib(i) } ] 
    |> Async.RunSynchronously 

printfn "The Fibonacci numbers are %A" fibs //I changed this line to be accurate 

System.Console.ReadKey(true) 

Se le specifiche non garantiva l'ordine di uscita, questo codice essere errato

+1

Questo mi ricorda il fatto che il metodo 'GetHashCode' di un intero restituisce semplicemente l'intero. È un dettaglio di implementazione, al contrario di un requisito di specifica. Consiglierei di non dipendere da questo comportamento. –

+3

@ChristopherStevenson - Ho fatto qualche ricerca e la specifica sembra implicare almeno che l'ordine di uscita è garantito –

Problemi correlati