c# stream async-await filestream c#-5.0

c# - ¿Se supone que Stream.ReadAsync y Stream.WriteAsync alteran la posición del cursor sincrónicamente antes de regresar o una vez que la operación se completa?



async-await filestream (1)

¿Puede alguien proporcionar algún tipo de información autorizada sobre si la antigua limitación BeginRead todavía se aplica a ReadAsync o no?

Las mismas limitaciones se aplican para BeginRead y ReadAsync .

Los viejos métodos APM no han sido desaprobados. Todavía son totalmente compatibles y no hay nada de malo en usarlos. Sin embargo, los métodos de async son considerablemente más fáciles de usar, por lo que la documentación sugiere utilizarlos.

Todas estas "sobrecargas" async en estas antiguas clases usualmente consisten en llamar a BeginXXX y EndXXX o, como máximo, ambas opciones llamar a un método compartido (por ejemplo, FileStream.BeginReadAsync ). Nunca he visto ningún código (en el marco o de otro tipo) que tenga métodos de contenedor APM sobre el async .

Por lo tanto, al llamar a ReadAsync se producirá una llamada a BeginRead por lo que cualquier limitación se aplica a ambas. Además, dado que Stream no es seguro para subprocesos y no se anuncia como concurrente seguro (que es ligeramente diferente), es seguro asumir que no puede inundarlo con solicitudes async mismo tiempo.

He estado intentando implementar un Stream que admita ReadAsync y WriteAsync , y dada la escasez de la documentación , me cuesta entender cómo hacerlo correctamente. Específicamente, con respecto a la posición del cursor de la secuencia. Se hizo una pregunta similar aquí y aquí con respecto a la antigua función BeginRead . La documentación para esa función parecía indicar que no debería volverse a llamar a BeginRead hasta que se completaran las operaciones asincrónicas pendientes.

Dado que BeginRead ahora está en desuso, ya no se recomienda para un nuevo desarrollo y Stream se ha modificado significativamente para implementar las nuevas funciones Async, las cosas una vez más no están claras. (EDITAR: Usualmente este tipo de advertencia significa que las nuevas funciones se implementan directamente y las funciones antiguas llaman a las nuevas y solo están ahí para la compatibilidad con versiones anteriores, pero parece que ese no es el caso aquí).

Las funciones ReadAsync y WriteAsync están definidas de modo que no toman la posición de flujo de lectura / escritura deseada como lo hacen sus contrapartes de Win32 (una opción de diseño muy pobre en mi opinión), sino que dependen de la posición actual de la implementación de la secuencia. Esa situación está bien si se cumple una de dos condiciones:

  1. ReadAsync y WriteAsync deben tomar la posición actual del cursor para que la use la operación y actualizarla como si la operación se completara (o no actualizarla en absoluto) antes de devolver la Task , o
  2. No se pueden realizar llamadas a ReadAsync o WriteAsync hasta que se hayan completado todas las llamadas asincrónicas anteriores.

Fuera de esas dos condiciones, la persona que llama nunca puede estar segura de la posición en la que ocurrirá la lectura o escritura porque las operaciones asíncronas pendientes podrían alterar la posición de la secuencia entre cualquier Seek y llamada a ReadAsync o WriteAsync . Ninguna de estas condiciones está documentada como un requisito, así que me pregunto cómo se supone que funcione.

Mi prueba de Whitebox parece indicar que al menos para la versión FileStream de Stream , la posición de la secuencia se actualiza de forma asíncrona, lo que parece indicar que la segunda condición (solo una operación pendiente permitida) sigue siendo la requerida, pero parece que una seria limitación (ciertamente excluye cualquier tipo de implementación interna de dispersión).

¿Puede alguien proporcionar algún tipo de información autorizada sobre si la antigua limitación BeginRead todavía se aplica a ReadAsync o no?