2012-06-09 11 views
6

No soy un chico de C# yo soy más un tipo de Objective-C, pero últimamente he visto muchas implementaciones de:Acción <T> vs Standard Volver

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

En lugar de:

public ReturnType Method(params...) 

Uno de los ejemplos de esto es MVVM Light Framework, allí el desarrollador implementa el contrato (e implementación) del servicio de datos utilizando el primer enfoque, por lo que mi pregunta es: ¿por qué? Es solo cuestión de me gusta o es el primer enfoque asincronous por defecto (dado el puntero de la función). Si eso es cierto, ¿el retorno estándar es la muerte? Lo pregunto porque personalmente me gusta que el segundo enfoque sea más claro para mí cuando veo una API.

+0

En caso de que no se haya encontrado con la Biblioteca de tareas paralelas, las bibliotecas que ofrecen métodos asíncronos normalmente * ofrecerán la Tarea Método (params ...) en lugar de realizar una devolución de llamada, pero puede no ser opción para las bibliotecas que necesitan trabajar con frameworks que no tienen soporte de Tarea (por ejemplo, Silverlight tiene la Tarea agregada en la versión 5, por lo que cualquier cosa Silverlight 4 o anterior necesitaría quedarse con callbacks o algún otro patrón) –

+0

@JamesManning He visto implementaciones del TPL que parecen bastante claras. ¿Están ellos -tras las sábanas- igual? –

+0

Creo que eso dependería de lo que sea la biblioteca de implementación. Conceptualmente, el TPL es un poco "mejor" (en mi humilde opinión) porque maneja cosas como cancelaciones y excepciones.Con las nuevas funciones de idioma, también puede escribir lo que se siente como código sincrónico utilizando la palabra clave await, que le permite evitar tener que escribir métodos de devolución de llamada, permitiendo que el compilador reescriba el método para que lo haga por usted. –

Respuesta

10

A diferencia de la API que devuelve ReturnType, una versión con devolución de llamada puede devolverse de inmediato y realizar la devolución de llamada más tarde. Esto puede ser importante cuando el valor para devolver no está disponible de inmediato, y obtenerlo implica un retraso considerable. Por ejemplo, y la API que solicita los datos de un servicio web puede tomar un tiempo considerable. Cuando no se requiere que los datos del resultado continúen, puede iniciar una llamada y proporcionar una devolución de llamada asincrónica. De esta forma, la persona que llama podría proceder de inmediato y procesar las notificaciones cuando estén disponibles.

Considere una API que toma una URL de una imagen y devuelve una representación en memoria de la imagen. Si su API es

Image GetImage(URL url) 

y sus usuarios tienen que tirar de diez imágenes, ellos tienen necesidad de esperar por cada imagen que se cargue antes de solicitar el siguiente, o iniciar múltiples hilos de forma explícita.

Por otro lado, si su API es

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

continuación, los usuarios de la API iniciaría las diez peticiones al mismo tiempo, y mostrar las imágenes a medida que estén disponibles de forma asíncrona. Este enfoque simplifica enormemente la programación de subprocesos que los usuarios deben hacer.

+0

¿Conoces algún equivalente en Java? – dantuch

+2

@dantuch Java no tiene delegados, por lo que no hay un equivalente directo. Pero puedes hacer algo similar usando una interfaz con un único método. Y luego podría usar una clase anónima para implementarlo. – svick

3

El primer método es probable que sea un método asincrónico, donde el método retorna inmediatamente y se llama a la devolución de llamada una vez que la operación ha finalizado.

El segundo método es la forma estándar de hacer retornos de métodos para métodos (sincrónicos) en C#.

Por supuesto, los diseñadores de API son libres de hacer cualquier firma que parezcan adecuadas; y podría haber otros detalles subyacentes para justificar el estilo de devolución de llamada. Pero, como regla general, si ve el estilo de devolución de llamada, espera que el método sea asincrónico.