2014-06-16 5 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 정렬 원래 작업을 갖는다

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

주문. 이렇게하면 출력 목록이 입력과 동일한 순서로 유지됩니다.

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) 

사양 출력 순서를 보장하지 않은 경우,이 코드는 다음과 같습니다 -

는 UPDATE

사양 적어도 순서가 고정되어 있음을 의미하는 것으로 보인다

은이 코드를 포함 틀리다.

+1

이것은 정수의'GetHashCode' 메소드가 단지 정수를 반환한다는 사실을 상기시켜줍니다. 스펙 요구 사항과 달리 구현 세부 사항입니다. 나는 그 행동에 의존하지 않는 것이 좋습니다. –

+3

@ChristopherStevenson - 나는 파기를했는데 사양은 최소한 출력 순서가 보장된다는 것을 의미하는 것 같습니다. –