2012-02-29 27 views
12

Nhìn vào:MailboxProcessor.PostAndReply thiết kế lựa chọn

member this.PostAndReply : (AsyncReplyChannel<'Reply> -> 'Msg) * ?int -> 'Reply 

Tôi không thể hiểu tại sao chữ ký trông rất phản trực giác đối với tôi. Những gì chúng tôi muốn làm là đăng một tin nhắn cho một đại lý và chờ trả lời. Tại sao chúng ta phải cho anh ta một chức năng kỳ lạ như một 'thông điệp'?

Xem lại đoạn này MSDN:

let rec loop() = 
    printf "> " 
    let input = Console.ReadLine() 
    printThreadId("Console loop") 
    let reply = agent.PostAndReply(fun replyChannel -> input, replyChannel) 
    if (reply <> "Stopping.") then 
     printfn "Reply: %s" reply 
     loop() 
    else 
     () 
loop() 

Tôi thà thích một cái gì đó như thế này:

member this.PostAndReply : 'Msg * ?int -> 'Reply 

Cảm ơn

Trả lời

9

chữ ký kiểu này trông khá khó hiểu khi bạn nhìn thấy nó cho lần đầu tiên, nhưng nó có ý nghĩa.

Thiết kế F # thư viện
Ý tưởng đằng sau sự là khi bạn gọi PostAndReply bạn cần phải cung cấp cho nó một chức năng rằng:

  • xây dựng một thông điệp của loại 'Msg (được gửi đến tác nhân)
  • sau khi thời gian chạy F # tạo kênh để gửi tin nhắn lại cho người gọi (kênh được biểu diễn dưới dạng giá trị loại AsyncReplyChannel<'Reply>).

Thư bạn xây dựng cần chứa kênh trả lời, nhưng thư viện F # không biết cách bạn muốn đại diện cho thư của mình (và vì vậy nó không biết cách bạn muốn lưu trữ kênh trả lời trong thư). Kết quả là, thư viện yêu cầu bạn viết một hàm sẽ xây dựng thông điệp cho tác nhân sau khi hệ thống xây dựng kênh.

đề nghị thay thế của bạn
Vấn đề với đề nghị của bạn là nếu PostAndReply có một loại 'Msg -> 'Reply, thông điệp mà tác nhân nhận được sau khi nó gọi Receive sẽ là của các loại sau đây:

'Msg * AsyncReplyChannel<'Reply> 

. .. vì vậy mọi tin nhắn nhận được cho đại lý cũng sẽ phải mang theo một kênh để gửi trả lời. Tuy nhiên, có thể bạn không muốn gửi trả lời cho mọi thư đã nhận, vì vậy điều này sẽ không thực sự hiệu quả. Có lẽ bạn có thể sử dụng một cái gì đó như:

'Msg * option<AsyncReplyChannel<'Reply>> 

... nhưng đó chỉ là trở nên phức tạp hơn (và nó vẫn không phải là hoàn toàn đúng, bởi vì bạn chỉ có thể trả lời một số tin nhắn từ 'Msg, nhưng không phải cho tất cả trong số họ).

+0

Ok cảm ơn, tôi hiểu. Nếu đó là tôi, tôi sẽ yêu cầu trong hàm tạo một tham số bổ sung: một hàm xây dựng một thông điệp từ một AsyncReplyChannel ('AsyncReplyChannel <'Reply> -> 'Msg') bổ sung vào phần thân của tác nhân. Thật vậy, từ quan điểm trung tâm của người dùng, tôi không hiểu tại sao mọi người muốn giới thiệu các cách khác nhau để xây dựng một msg từ một kênh trả lời, khi gọi 'PostAndReply', mặc dù nó sẽ ít chung chung hơn. – Okay

+2

@Okay - Điều đó sẽ không hoạt động.Nó khá phổ biến khi có các cách khác nhau để xây dựng các giá trị ''Msg' chứa' AsyncReplyChannel'. Ví dụ, tác nhân xếp hàng chặn (xem MSDN http://msdn.microsoft.com/en-us/library/hh297096.aspx) có hai thông báo khác nhau mà cả hai đều mang một kênh trả lời và vì vậy bạn có hai cách để xây dựng thông điệp . Điều đó nói rằng, tôi đồng ý rằng chữ ký khá khó hiểu. Nó sẽ là tốt đẹp để có lựa chọn dễ đọc hơn, nhưng tôi chỉ không thể nghĩ rằng đó có thể là ... –

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