sirve que para metodo example ejemplos ejemplo await async c# .net async-await .net-4.5

que - task await c# ejemplo



async/await y abriendo un FileStream? (3)

Encontré la siguiente pregunta cuando ReadAsync determinar si estaba usando los métodos de ReadAsync como ReadAsync y CopyToAsync correctamente: C # 4.5 rendimiento de lectura de lectura sincronización contra asíncrono

En esta pregunta leí lo siguiente en la respuesta aceptada:

En particular, su prueba "asíncrona" no usa E / S asíncrona; con los flujos de archivos, tiene que abrirlos explícitamente como asíncronos o, de lo contrario, solo está realizando operaciones síncronas en un hilo de fondo.

En su código de E / S asíncrono, estaba usando lo siguiente para abrir FileStream ''asincrónicamente'':

var file = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read, 4096, true)

Así que me preguntaba si pretendes usar métodos como CopyToAsync si deberías abrir el FileStream subyacente como se muestra arriba, en lugar de hacer algo simple como lo siguiente:

File.Open(filename, FileMode.Open)

Así es como el ejemplo en la documentación real para CopyToAsync demuestra CopyToAsync abrir el FileStream subyacente: https://msdn.microsoft.com/en-us/library/hh159084(v=vs.110).aspx

Si no importa de qué manera se abre el FileStream subyacente, ¿qué hace el parámetro useAsync del constructor FileStream ?


Así que me preguntaba si pretendes usar métodos como CopyToAsync si deberías abrir el FileStream subyacente como se muestra arriba, en lugar de hacer algo simple como File.Open ?

Usé ILSpy para descompilar y mirar File.Open .

public static FileStream Open(string path, FileMode mode) { return File.Open(path, mode, (mode == FileMode.Append) ? FileAccess.Write : FileAccess.ReadWrite, FileShare.None); }

Que llama a esto:

public static FileStream Open(string path, FileMode mode, FileAccess access, FileShare share) { return new FileStream(path, mode, access, share); }

Y este constructor de FileStream específico pasa en false para el parámetro useAsync . Entonces, sí parece importar. Sin embargo, aún puede invocar las API async y seguirá funcionando como cabría esperar.

Como dice Hans Passant:

La llamada subyacente a CreateFile() luego usa la opción FILE_FLAG_OVERLAPPED . Esto permite la E / S superpuesta, un mecanismo que permite lecturas y escrituras asíncronas en el nivel de winapi.

La clase FileStream tiene un bool _isAsync , y significa "Si no se admite el IO asíncrono en esta plataforma o si este FileStream no se abrió con FileOptions.Asynchronous.".

Nuevamente, aún obtienes una Task que representa esa operación asíncrona como deseas.


Así que me preguntaba si tiene la intención de utilizar métodos como CopyToAsync si debería abrir el FileStream subyacente como se muestra arriba.

Sí. La razón es sobre todo histórica.

Primero, en Windows, los HANDLE s (incluidos los manejadores de archivos) deben abrirse / crearse explícitamente con un indicador asíncrono si desea realizar operaciones asincrónicas ( OVERLAPPED ) en ellos .

Sin embargo, la antigua línea de Windows 95/98 / ME solo admitía operaciones asíncronas en el puerto serie y los controladores IOCTL (controlador de dispositivo) . La E / S asíncrona en los archivos de disco no era compatible con esa línea de plataforma. Y el .NET original era compatible con 98 / ME , por lo que el FileStream original solo usaba E / S síncrona. Creo (pero no estoy absolutamente seguro) que los métodos APM (como FileStream.BeginRead ) en Win98 / ME probablemente se implementaron usando los llamados "delegados asíncronos" (que simplemente ejecutan un método sincrónico como FileStream.Read en un grupo de subprocesos hilo).

Por lo tanto, esa es la razón histórica por la que los manejadores de archivos no se abrieron con el indicador asíncrono de forma predeterminada.

Que es como el ejemplo en la documentación real para CopyToAsync demuestra

Desafortunadamente, muchos de los ejemplos de MSDN son de baja calidad. Están bien si te acercas a ellos desde la perspectiva de "aquí hay un ejemplo de cómo llamar a este método específico", pero no tanto desde la perspectiva de "aquí hay un ejemplo de código de calidad de producción que utiliza este método".


El sitio web de MSDN dice:

useAsync

Tipo: System.Boolean

Especifica si se debe utilizar E / S asíncrona o E / S síncrona. Sin embargo, tenga en cuenta que es posible que el sistema operativo subyacente no admita la E / S asíncrona, por lo que, al especificar true , el identificador podría abrirse de forma síncrona según la plataforma. Cuando se abren de forma asíncrona, los métodos BeginRead y BeginWrite funcionan mejor en lecturas o escrituras grandes, pero pueden ser mucho más lentos para las lecturas o escrituras pequeñas. Si la aplicación está diseñada para aprovechar las ventajas de la E / S asíncrona, establezca el parámetro useAsync en true . Usar la E / S asíncrona correctamente puede acelerar las aplicaciones hasta en un factor de 10, pero usarla sin rediseñar la aplicación para la E / S asíncrona puede disminuir el rendimiento hasta en un factor de 10.