2012-06-09 2 views
6

Io non sono un C# ragazzo io sono più un ragazzo Objective-C, ma ultimamente ho visto un sacco di implementazioni di:Azione <T> vs ritorno standard

public void Method(Action<ReturnType> callback, params...) 

Invece di:

public ReturnType Method(params...) 

Uno degli esempi di questo è MVVM Light Framework, in cui lo sviluppatore implementa il contratto di servizio dati (e implementazione) utilizzando il primo approccio, quindi la mia domanda è: perché questo? È solo questione di like o è il primo approccio asincrono per default (dato il puntatore della funzione). Se è vero, è la morte di ritorno standard? Chiedo perché personalmente mi piace che il secondo approccio mi sia più chiaro quando vedo un'API.

+0

Nel caso in cui non lo si sia già incontrato, con la Libreria parallela attività, le librerie che offrono metodi asincroni * tipicamente * offrono Task Method (params ...) invece di richiamare, ma che potrebbe non essere un opzione per le librerie che hanno bisogno di lavorare con framework che non hanno il supporto Task (ad esempio, Silverlight ha ottenuto l'attività aggiunta nella versione 5, quindi qualsiasi cosa Silverlight 4 o prima avrebbe bisogno di attaccare con callback o qualche altro pattern) –

+0

@JamesManning Ho visto implementazioni del TPL che sembra abbastanza chiaro. Sono - dietro le coperte - lo stesso? –

+0

Penso che dipenderebbe da qualunque sia la libreria di implementazione. Concettualmente, il TPL è un po '"migliore" (IMHO) perché gestisce cose come cancellazioni ed eccezioni.Con le nuove funzionalità del linguaggio, puoi anche scrivere ciò che "sente" come il codice sincrono usando la parola chiave await, che ti evita di dover scrivere metodi di callback, lasciando che il compilatore riscriva il metodo per farlo. –

risposta

10

A differenza dell'API che restituisce ReturnType, una versione con richiamata può tornare immediatamente ed eseguire la richiamata in un secondo momento. Questo può essere importante quando il valore da restituire non è immediatamente disponibile e il suo recupero comporta un considerevole ritardo. Ad esempio, e l'API che richiede i dati da un servizio Web potrebbe richiedere molto tempo. Quando non è necessario procedere con i dati del risultato, è possibile avviare una chiamata e fornire una richiamata asincrona. In questo modo il chiamante sarebbe in grado di procedere immediatamente e di elaborare le notifiche quando saranno disponibili.

Considerare un'API che accetta un URL di un'immagine e restituisce una rappresentazione in memoria dell'immagine. Se la vostra API è

Image GetImage(URL url) 

e gli utenti hanno bisogno di tirare dieci immagini, avrebbero sia bisogno di aspettare per ogni immagine per terminare il caricamento prima di richiedere il successivo, o iniziare più thread in modo esplicito.

D'altra parte, se la vostra API è

void Method(Action<Image> callback, URL url) 

poi gli utenti del tuo API sarebbe avviare tutte le dieci richieste, allo stesso tempo, e visualizzare le immagini non appena saranno disponibili in modo asincrono. Questo approccio semplifica enormemente la programmazione dei thread che gli utenti devono fare.

+0

Conosci qualche equivalente in Java? – dantuch

+2

@dantuch Java non ha delegati, quindi non esiste un equivalente diretto. Ma puoi fare qualcosa di simile usando un'interfaccia con un singolo metodo. E potresti quindi utilizzare la classe anonima per implementarla. – svick

3

Il primo metodo è probabile che sia un metodo asincrono, in cui il metodo restituisce immediatamente e il callback viene chiamato una volta terminata l'operazione.

Il secondo metodo è il metodo standard per restituire metodi per i metodi (sincroni) in C#.

Ovviamente, i progettisti di API sono liberi di apportare qualsiasi firma sembrano adatti; e potrebbero esserci altri dettagli sottostanti per giustificare lo stile di callback. Ma, come regola generale, se vedi lo stile di callback, aspettati che il metodo sia asincrono.