Nota:
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
Use la característica asincrónica para acceder a los archivos. Al utilizar la función Async, puede llamar a métodos asincrónicos sin usar callbacks ni dividir el código entre varios métodos o expresiones lambda. Para que el código sincrónico sea asincrónico, llame a un método asincrónico en lugar de un método sincrónico y agregue algunas palabras clave al código.
Considere la posibilidad de agregar asincronía a las llamadas de acceso a archivos por estos motivos:
La asincronía hace que las aplicaciones de interfaz de usuario tengan mayor capacidad de respuesta porque el subproceso de interfaz de usuario que inicia la operación puede realizar otro trabajo. Si el subproceso de interfaz de usuario debe ejecutar código que tarda mucho tiempo (por ejemplo, más de 50 milisegundos), la interfaz de usuario podría inmovilizarse hasta que se complete la E/S y el subproceso de la interfaz de usuario puede volver a procesar la entrada del teclado y el mouse y otros eventos.
La asincronía mejora la escalabilidad de ASP.NET y otras aplicaciones basadas en servidor al reducir la necesidad de subprocesos. Si la aplicación usa un subproceso dedicado por respuesta y se administran mil solicitudes simultáneamente, se necesitan mil subprocesos. Las operaciones asincrónicas a menudo no necesitan usar un hilo durante la espera. Usan el subproceso existente de finalización de E/S brevemente al final.
La latencia de una operación de acceso a archivos podría ser muy baja en condiciones actuales, pero la latencia podría aumentar considerablemente en el futuro. Por ejemplo, un archivo se puede mover a un servidor que se encuentra en todo el mundo.
La sobrecarga agregada del uso de la característica asincrónica es pequeña.
Se pueden ejecutar varias operaciones de E/S asincrónicas sin bloquear el subproceso que realiza la llamada.
Ejecución de los ejemplos
Para ejecutar los ejemplos de este tema, cree una aplicación WPF o una aplicación de Windows Forms y agregue un botón. En el evento Click del botón, agregue una llamada al primer método de cada ejemplo.
En los ejemplos siguientes, incluya las siguientes Imports declaraciones.
Imports System
Imports System.Collections.Generic
Imports System.Diagnostics
Imports System.IO
Imports System.Text
Imports System.Threading.Tasks
Uso de la clase FileStream
Los ejemplos de este tema usan la FileStream clase , que tiene una opción que hace que la E/S asincrónica se produzca en el nivel de sistema operativo. Con esta opción, puede evitar el bloqueo de un hilo ThreadPool en muchos casos. Para habilitar esta opción, especifique el useAsync=true argumento o options=FileOptions.Asynchronous en la llamada al constructor.
No puede utilizar esta opción con StreamReader y StreamWriter si las abre directamente especificando una ruta de archivo. En cambio, puede usar esta opción si les proporciona un Stream que ha abierto la clase FileStream. Las llamadas asincrónicas son más rápidas en las aplicaciones de interfaz de usuario incluso si se bloquea un subproceso threadPool, ya que el subproceso de interfaz de usuario no está bloqueado durante la espera.
Escribir texto
En el ejemplo siguiente se escribe texto en un archivo. En cada instrucción await, el método finaliza inmediatamente. Cuando se complete la E/S de archivo, el método se reanuda en la instrucción que sigue a la instrucción await. El modificador asincrónico está en la definición de métodos que usan la instrucción await.
Public Async Sub ProcessWrite()
Dim filePath = "temp2.txt"
Dim text = "Hello World" & ControlChars.CrLf
Await WriteTextAsync(filePath, text)
End Sub
Private Async Function WriteTextAsync(filePath As String, text As String) As Task
Dim encodedText As Byte() = Encoding.Unicode.GetBytes(text)
Using sourceStream As New FileStream(filePath,
FileMode.Append, FileAccess.Write, FileShare.None,
bufferSize:=4096, useAsync:=True)
Await sourceStream.WriteAsync(encodedText, 0, encodedText.Length)
End Using
End Function
El ejemplo original tiene la instrucción Await sourceStream.WriteAsync(encodedText, 0, encodedText.Length), que es una contracción de las dos instrucciones siguientes:
Dim theTask As Task = sourceStream.WriteAsync(encodedText, 0, encodedText.Length)
Await theTask
La primera instrucción devuelve una tarea e inicia el procesamiento de archivos. La segunda instrucción con await finaliza el método inmediatamente y devuelve otra tarea. Después, cuando se complete el procesamiento de archivos, la ejecución vuelve a la instrucción que sigue a la instrucción await. Para obtener más información, vea Flujo de control en programas asincrónicos (Visual Basic).
Leer texto
En el ejemplo siguiente se lee texto de un archivo. El texto se almacena temporalmente y, en este caso, se coloca en StringBuilder. A diferencia de en el ejemplo anterior, la evaluación de await genera un valor. El ReadAsync método devuelve un Task<Int32>, por lo que la evaluación de await genera un Int32 valor (numRead) una vez completada la operación. Para obtener más información, vea Tipos de retorno de Async (Visual Basic).
Public Async Sub ProcessRead()
Dim filePath = "temp2.txt"
If File.Exists(filePath) = False Then
Debug.WriteLine("file not found: " & filePath)
Else
Try
Dim text As String = Await ReadTextAsync(filePath)
Debug.WriteLine(text)
Catch ex As Exception
Debug.WriteLine(ex.Message)
End Try
End If
End Sub
Private Async Function ReadTextAsync(filePath As String) As Task(Of String)
Using sourceStream As New FileStream(filePath,
FileMode.Open, FileAccess.Read, FileShare.Read,
bufferSize:=4096, useAsync:=True)
Dim sb As New StringBuilder
Dim buffer As Byte() = New Byte(&H1000) {}
Dim numRead As Integer
numRead = Await sourceStream.ReadAsync(buffer, 0, buffer.Length)
While numRead <> 0
Dim text As String = Encoding.Unicode.GetString(buffer, 0, numRead)
sb.Append(text)
numRead = Await sourceStream.ReadAsync(buffer, 0, buffer.Length)
End While
Return sb.ToString
End Using
End Function
Varias operaciones de E/S asincrónicas
En el ejemplo siguiente se inician varias operaciones de escritura asincrónicas. El tiempo de ejecución pone en cola estas operaciones y la implementación subyacente podría usar subprocesos de E/S asincrónicos del sistema operativo (SO) o de grupo de subprocesos en función de la plataforma y la configuración, por lo que la simultaneidad real depende del sistema operativo y del hardware. Para cada archivo, el WriteAsync método devuelve una tarea que se agrega a una lista de tareas. La Await Task.WhenAll(tasks) instrucción sale del método y se reanuda dentro del método cuando se completa el procesamiento de archivos para todas las tareas.
En el ejemplo se cierran todas las FileStream instancias de un Finally bloque una vez completadas las tareas. Si en lugar de ello, cada FileStream se ha creado en una instrucción Using, la FileStream se podría desechar antes de completarse la tarea.
El enfoque asincrónico evita bloquear el subproceso de llamada mientras la E/S está pendiente. En muchos casos, las mejoras de rendimiento dependen del sistema operativo, el hardware y, en algunas plataformas, el comportamiento del entorno de ejecución de .NET, como los límites y la programación del grupo de subprocesos.
Public Async Sub ProcessWriteMult()
Dim folder = "tempfolder\"
Dim tasks As New List(Of Task)
Dim sourceStreams As New List(Of FileStream)
Try
For index = 1 To 10
Dim text = "In file " & index.ToString & ControlChars.CrLf
Dim fileName = "thefile" & index.ToString("00") & ".txt"
Dim filePath = folder & fileName
Dim encodedText As Byte() = Encoding.Unicode.GetBytes(text)
Dim sourceStream As New FileStream(filePath,
FileMode.Append, FileAccess.Write, FileShare.None,
bufferSize:=4096, useAsync:=True)
Dim theTask As Task = sourceStream.WriteAsync(encodedText, 0, encodedText.Length)
sourceStreams.Add(sourceStream)
tasks.Add(theTask)
Next
Await Task.WhenAll(tasks)
Finally
For Each sourceStream As FileStream In sourceStreams
sourceStream.Close()
Next
End Try
End Sub
Al usar los WriteAsync métodos y ReadAsync , puede especificar un CancellationToken para cancelar la operación a mitad del flujo. Para obtener más información, consulte Fine-Tuning Your Async Application (Visual Basic) y Cancellation in Managed Threads.
Consulte también
- Programación asincrónica con Async y Await (Visual Basic)
- Async Return Types (Visual Basic) (Tipos de valor devuelto de Async [Visual Basic])
- Flujo de control en programas asincrónicos (Visual Basic)