2012-04-25 18 views
6

Me gustaría leer y escribir bytes y tipos de valores estructurados, de forma asincrónica, sin tener que preocuparme por los decodificadores y el byte-cambio: ¿hay algo por ahí que me permita hacer eso?BinaryReader asincrónico y BinaryWriter en .Net?

+0

¿Qué tal 'Stream.BeginRead', etc.? –

+0

Eso está en Stream, no en BinaryReader y BinaryWriter. – Henrik

+0

desea leer/escribir bytes; para eso no se necesita un 'BinaryReader' /' BinaryWriter'; de hecho, no ayudan mucho con ese fin. –

Respuesta

7

No es posible con BinaryReader o BinaryWriter. Se podía leer simultáneamente desde el BaseStream subyacente, pero los documentation indica lo siguiente:

Uso de la secuencia subyacente al leer o durante el uso de la BinaryReader puede causar la pérdida de datos y la corrupción. Por ejemplo, los mismos bytes se pueden leer más de una vez, se pueden omitir bytes o la lectura de caracteres puede volverse impredecible.

Por lo tanto, la única forma es ejecutar su propia implementación. Pero el beneficio de hacerlo es discutible. Marco Greg de Microsoft añadió el siguiente comentario al artículo de blog Should I expose asynchronous wrappers for synchronous methods?:

Jon: La razón por la que el BinaryReader/escritor no tienen métodos XxxAsync es que los métodos sobre los tipos normalmente Lectura/Escritura sólo muy pocos bytes de un flujo subyacente que se ha abierto previamente. En la práctica, los datos se almacenan en caché con frecuencia y el tiempo requerido para obtener los datos de la fuente subyacente suele ser tan pequeño que no vale la pena hacerlo de forma asíncrona.

Cabe destacar que hay algunos métodos en estos tipos que en algunas circunstancias pueden transferir grandes cantidades de datos (por ejemplo, ReadString). Más adelante en la línea, las versiones de Async para esos métodos pueden o no agregarse, pero es poco probable que suceda en el futuro inmediato.

En general, solo debe considerar los métodos Async IO si la cantidad de datos que está leyendo es significativa (al menos varios cientos o miles de bytes), o si está accediendo a un recurso por primera vez (por ejemplo, un primer leer desde un archivo puede requerir girar el disco incluso si está leyendo un byte).

Esto suena razonable. Si necesita una solución, existen varias soluciones además de rodar su propia BinaryReader/BinaryWriter. Se puede ejecutar en un hilo separado (que puede ser ineficiente) o si usted está dispuesto a cambiar el protocolo de formato de archivo o alambre que podría utilizar este patrón (pseudo-código):

//read packet length 
await stream.ReadAsync(buffer); 
var packetLength=convertToInt(buffer); 

//read complete packet asynchronously 
await stream.ReadAsync(buffer,packetLength); 

//process packet with BinaryReader 
using(var br=new BinaryReader(new MemoryStream(buffer)) 
{ 
    //... 
} 

Tenga en cuenta que este el patrón solo es útil si el búfer completo se adapta fácilmente a la memoria y el rendimiento puede verse afectado.

Cuestiones relacionadas