2012-10-09 25 views
9

Con las ventajas de la E/S asincrónica y ahora es bastante fácil de codificar y componer (utilizando los métodos Await y TAP) me pregunto si deberíamos usar asincronización de manera predeterminada y solo ajustar el rendimiento utilizando la sincronización cuando sea necesario.¿Deberíamos cambiar para usar la E/S asincrona por defecto?

Async I/O libera el hilo de llamada y permite hacer algo más mientras espera el resultado. Por otro lado, async I/O es un poco más lento que la sincronización.

Para imponer IU receptivas, los diseñadores de WinRT consideraron aceptable ofrecer métodos solo asíncronos.

AFAIK La E/S de archivos de Windows internamente es asincrónica. Al ver esto ingenuamente, no está claro para mí, por qué el archivo asíncrono de E/S en .NET debería ser más lento que la sincronización en absoluto.

Generalmente prefiero la simplicidad y la solidez y solo sintonizo el rendimiento donde sea necesario. En el pasado, utilizábamos la sincronización de forma predeterminada con la excepción de llamar a algunos servicios y donde plataformas como el teléfono aplicaban asincronías. Rara vez ajustamos mediante el uso de asincrónico.

+0

El [pfxteam blog] (http://msdn.microsoft.com/en-us/magazine/jj133817.aspx) contiene información interesante en este contexto: * "Tenga en cuenta que no agregamos versiones asíncronas de APIs que tenían una granularidad muy pequeña, como TextReader.Peek. La razón es que las API asíncronas también agregan algunos gastos generales y queríamos evitar que los desarrolladores se desvíen accidentalmente en la dirección equivocada. Esto también significa que decidimos específicamente no ofrecer versiones asíncronas para los métodos. en BinaryReader o BinaryWriter .... * –

Respuesta

13

El uso de async IO se ha vuelto muy fácil con C# 5, pero todavía hay un costo de productividad asociado. Por ejemplo, es necesario rociar nuevas palabras clave donde antes no era necesario. Tienes que cambiar el tipo de devolución de tu método.

Si luego decide que un método debe hacer IO, debe cambiar toda la cadena de llamadas para cambiar a async. Es un cambio no local que se extiende a otros módulos.

No se puede perfilar async IO. Las herramientas de creación de perfiles no recogen nada. Si detiene el depurador, no hay nada en ninguna de las pilas de subprocesos. Nadie parece estar haciendo nada. Eso es porque un IO asíncrono no contiene un hilo. Es solo una estructura de datos (un objeto en el kernel).

La decisión también depende del tipo de aplicación. En una aplicación WinForms o WPF prefiero ir con asincronía porque se integra muy bien en el hilo de la interfaz de usuario.

En una configuración de ASP.NET/WCF, la principal ventaja es que no agota el grupo de subprocesos mientras llama a los servicios back-end de larga ejecución. Si no tiene ese problema, y ​​creo que esto es bastante raro, obtiene muy poco de async IO. De hecho, pierdes el rendimiento por defecto.

En una configuración de Metro, la decisión ha sido tomada para usted. Microsoft (legítimamente) eligió intercambiar la productividad del desarrollador por la experiencia del usuario.

Por lo tanto, no es una decisión clara. Los pros y los contras son bastante débiles en este punto. Por esa razón, me abstengo de dar una recomendación inequívoca. Depende mucho del caso específico.

8

Recomendaría usar async cuando tiene una operación naturalmente asíncrona, y el código síncrono de lo contrario. Es cierto que async es un poco más lento, pero en la mayoría de los casos es como "encender la radio de tu Hummer" más lento.

En programas de IU, async aumenta la capacidad de respuesta. En aplicaciones de servidor, async aumenta la escalabilidad.

AFAIK La E/S de archivos de Windows internamente es asincrónica. Al ver esto ingenuamente, no está claro para mí, por qué asincronizar archivos de E/S en .NET debería ser más lento que sincronizar en absoluto.

El código asíncrono es más lento porque tiene que asignar estructuras para rastrear la operación asíncrona; el código síncrono solo usa el hilo actual (y su pila). Por lo tanto, la operación en sí no es más lenta, pero en general hay una ligera disminución de velocidad debido a una mayor presión sobre el recolector de basura.

Generalmente prefiero la simplicidad y la solidez y solo sintonizo el rendimiento donde sea necesario.

Estoy de acuerdo. Si tiene una operación que es naturalmente asincrónica (como E/S), exponga una API async. Y si tiene una operación que es naturalmente sincrónica, exponga una API síncrona. Stephen Toub tiene un par de publicaciones excelentes en este blog (here y here).

Cuestiones relacionadas