2014-06-16 16 views
6

Có phải các kết quả từ hoạt động Async của F # được đảm bảo đến trong các lệnh đặt hàng không? Mã mẫu của tôi trả về kết quả theo thứ tự, nhưng tôi không thể tìm thấy bất kỳ đề cập nào trong tài liệu MSDN hoặc thông số F #, đảm bảo rằng phải là trường hợp - đó không phải là trùng hợp ngẫu nhiên.Are F # Async.Kết quả song song có được đảm bảo theo thứ tự không?

Đây là mẫu mã của tôi:

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" 

Và đây là đầu ra.

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

Bạn có thể thấy rằng, trong lần chạy này, các hàm async hoàn thành theo thứ tự không xác định, nhưng mảng kết quả được sắp xếp. Hành vi này có được đảm bảo không?

Trả lời

11

Hiện tại, nguồn của hàm được viết để đảm bảo việc này được thực thi. Nhìn vào control.fs around line #1300 cho định nghĩa, chúng ta có thể thấy các chức năng mà đặt kết quả vào mảng đầu ra là

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

chức năng này được gọi là trong phân khúc này

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

nơi tasks có nhiệm vụ ban đầu trong sắp xếp gọi món. Điều này đảm bảo rằng danh sách đầu ra là theo thứ tự như đầu vào.

CẬP NHẬT

Các spec ít nhất dường như ngụ ý rằng thứ tự là cố định - nó có chứa mã này:

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) 

Nếu spec không đảm bảo thứ tự xuất, mã này sẽ không đúng.

+1

Điều này nhắc tôi về thực tế rằng phương thức 'GetHashCode' của một số nguyên đơn giản trả về số nguyên. Đó là một chi tiết thực hiện, trái với yêu cầu cụ thể. Tôi khuyên bạn không nên tùy thuộc vào hành vi đó. –

+3

@ChristopherStevenson - Tôi đã thực hiện một số kỹ thuật đào và thông số dường như ít nhất ngụ ý rằng thứ tự đầu ra được đảm bảo –

Các vấn đề liên quan