2012-02-29 10 views
12

Guardando:MailboxProcessor.PostAndReply progettazione scelta

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

non riesco a capire perché la firma sembra così intuitivo per me. Quello che vogliamo fare è postare un messaggio a un agente e aspettare una risposta. Perché dobbiamo dargli una strana funzione di 'messaggio'?

rivedere questo frammento di codice 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() 

preferirei preferite qualcosa di simile:

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

Grazie

risposta

9

Questa firma tipo sembra piuttosto confusa quando lo vedi per la prima volta, ma ha senso.

Il progetto F # biblioteca
L'idea alla base della è che quando si chiama PostAndReply è necessario dare una funzione che :

  • costruisce un messaggio di tipo 'Msg (da inviare a l'agente)
  • dopo che il runtime F # crea un canale per l'invio di messaggi al chiamante (i canali sono rappresentati come valori di tipo AsyncReplyChannel<'Reply>).

Il messaggio che si costruisce deve contenere il canale di risposta, ma la libreria F # non sa come si desidera rappresentare i propri messaggi (e quindi non sa come si desidera memorizzare il canale di risposta nel messaggio). Di conseguenza, la libreria richiede di scrivere una funzione che costruirà il messaggio per l'agente dopo che il sistema ha creato il canale.

tuo suggerimento alternativa
Il problema con il vostro suggerimento è che se PostAndReply avuto il messaggio che l'agente riceve dopo che definisce un tipo 'Msg -> 'Reply, Receive sarebbe del tipo seguente:

'Msg * AsyncReplyChannel<'Reply> 

. .. quindi ogni messaggio ricevuto all'agente dovrebbe anche avere un canale per l'invio delle risposte. Tuttavia, probabilmente non vuoi inviare una risposta per ogni messaggio ricevuto, quindi questo non funzionerebbe. Forse si potrebbe usare qualcosa di simile a:

'Msg * option<AsyncReplyChannel<'Reply>> 

... ma questo è solo ottenere più complicato (e non è ancora abbastanza bene, perché si può rispondere solo ad alcuni messaggi di 'Msg, ma non a tutti).

+0

Ok grazie, vedo. Se fossi stato io, avrei richiesto al costruttore un parametro aggiuntivo: una funzione che costruisce un messaggio da un AsyncReplyChannel ('AsyncReplyChannel <'Reply> -> 'Msg') addizionalmente al corpo dell'agente. Infatti, da un punto di vista incentrato sull'utente, non riesco a capire perché la gente vorrebbe introdurre modi diversi per costruire un messaggio da un canale di risposta, quando si chiama 'PostAndReply', anche se sarebbe meno generico. – Okay

+2

@Okay - Non funzionerebbe neanche.È abbastanza comune avere diversi modi di costruire valori '' Msg' che contengono 'AsyncReplyChannel'. Ad esempio, l'agente della coda di blocco (vedi MSDN http://msdn.microsoft.com/en-us/library/hh297096.aspx) ha due messaggi diversi che hanno entrambi un canale di risposta e quindi hai due modi per costruire il messaggio . Detto questo, sono d'accordo sul fatto che la firma sia piuttosto confusa. Sarebbe bello avere un'alternativa più leggibile, ma non riesco a pensare a cosa potrebbe essere ... –

Problemi correlati