2014-06-16 42 views
6

F#的Async.Parallel操作的結果是否保證在訂單作業中提交?我的示例代碼按順序返回結果,但我無法在MSDN文檔或F#規範中找到任何提及,請確保此必須是就是這種情況 - 這並非巧合。F#Async.Parallel結果保證按順序嗎?

這裏是我的示例代碼:

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" 

而這裏的輸出。

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

您可以看到,在此次運行中,異步函數以不確定的順序完成,但結果數組已排序。這種行爲是否有保證?

回答

11

目前,函數的來源是這樣寫的,這個保證是強制執行的。縱觀control.fs around line #1300的定義中,我們可以看到,結果放置到輸出數組中的功能是

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

調用該函數在這一領域

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

其中tasks具有原始任務排序訂購。這保證了輸出列表與輸入順序相同。

UPDATE

該規範至少似乎暗示順序是固定的 - 它包含以下代碼:

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) 

如果規範不保證輸出順序是,該代碼不正確。

+1

這讓我想起整數的'GetHashCode'方法只返回整數的事實。這是一個實現細節,而不是規範要求。我會建議不要依賴於這種行爲。 –

+3

@ChristopherStevenson - 我做了一些挖掘,規範似乎至少暗示輸出順序是有保證的 –