E/S de archivos asincrónica

 

Publicado: octubre de 2016

Las operaciones asincrónicas permiten realizar operaciones de E/S que hacen un uso intensivo de recursos sin bloquear el subproceso principal. Esta consideración de rendimiento es especialmente importante en una aplicación de la Tienda Windows 8.x o una aplicación de Entity with relative path '../Token/desktop_appname_md.md' can not be found, for source topic '{"project_id":"3fedad16-eaf1-41a6-8f96-0c1949c68f32","entity_id":"dbdd55e7-d6b9-4f9e-8abb-ab0edd4457f7","entity_type":"Article","locale":"es-ES"}'. en que una operación de streaming prolongada puede bloquear el subproceso de interfaz de usuario y hacer que parezca que una aplicación ha dejado de responder.

A partir de .NET Framework 4.5, los tipos de E/S incluyen métodos asincrónicos para simplificar las operaciones asincrónicas. Un método asincrónico contiene Async en su nombre, como ReadAsync, WriteAsync, CopyToAsync, FlushAsync, ReadLineAsync y ReadToEndAsync. Estos métodos asincrónicos se implementan en clases de secuencias, como Stream, FileStream y MemoryStream, y en las clases de las que se usan para leer o escribir en secuencias, como TextReader y TextWriter.

En .NET Framework 4 y versiones anteriores, es necesario usar métodos como BeginRead y EndRead para implementar operaciones de E/S asincrónicas. Estos métodos siguen estando disponibles en .NET Framework 4.5 por compatibilidad con el código heredado; sin embargo, los métodos asincrónicos implementan las operaciones de E/S asincrónicas de una manera más sencilla.

A partir de Visual Studio 2012, Visual Studio proporciona dos palabras clave para la programación asincrónica:

  • El modificador Async (Visual Basic) o async (C#), que se utiliza para marcar un método que contiene una operación asincrónica.

  • El operador Await (Visual Basic) o await (C#), que se aplica al resultado de un método asincrónico.

Para implementar operaciones de E/S asincrónicas, use estas palabras clave junto con los métodos asincrónicos, como se muestra en los ejemplos siguientes. Para obtener más información, consulta Programación asincrónica con Async y Await.

En el ejemplo siguiente se muestra cómo usar dos objetos FileStream para copiar archivos de forma asincrónica de un directorio en otro. Observe que el controlador de eventos Click para el control Button está marcado con el modificador async porque llama a un método asincrónico.

Imports System.IO

Class MainWindow

    Private Async Sub Button_Click(sender As Object, e As RoutedEventArgs)
        Dim StartDirectory As String = "c:\Users\exampleuser\start"
        Dim EndDirectory As String = "c:\Users\exampleuser\end"

        For Each filename As String In Directory.EnumerateFiles(StartDirectory)
            Using SourceStream As FileStream = File.Open(filename, FileMode.Open)
                Using DestinationStream As FileStream = File.Create(EndDirectory + filename.Substring(filename.LastIndexOf("\"c)))
                    Await SourceStream.CopyToAsync(DestinationStream)
                End Using

            End Using
        Next
    End Sub

End Class

El ejemplo siguiente es similar al anterior, pero utiliza objetos StreamReader y StreamWriter para leer y escribir el contenido de un archivo de texto de forma asincrónica.

    Private Async Sub Button_Click(sender As Object, e As RoutedEventArgs)
        Dim UserDirectory As String = "c:\Users\exampleuser\"

        Using SourceReader As StreamReader = File.OpenText(UserDirectory + "BigFile.txt")
            Using DestinationWriter As StreamWriter = File.CreateText(UserDirectory + "CopiedFile.txt")
                Await CopyFilesAsync(SourceReader, DestinationWriter)
            End Using
        End Using
    End Sub

    Public Async Function CopyFilesAsync(Source As StreamReader, Destination As StreamWriter) As Task
        Dim buffer(4096) As Char
        Dim numRead As Integer

        numRead = Await Source.ReadAsync(buffer, 0, buffer.Length)
        Do While numRead <> 0
            Await Destination.WriteAsync(buffer, 0, numRead)
            numRead = Await Source.ReadAsync(buffer, 0, buffer.Length)
        Loop
        
    End Function

En el ejemplo siguiente se muestra el archivo de código subyacente y el archivo XAML que se usan para abrir un archivo como Stream en una aplicación de la Tienda Windows 8.x y leer su contenido mediante una instancia de la clase StreamReader. Utiliza métodos asincrónicos para abrir el archivo como secuencia y leer su contenido.

Imports System.Text
Imports System.IO
Imports Windows.Storage.Pickers
Imports Windows.Storage

NotInheritable Public Class BlankPage
    Inherits Page

    

    Private Async Sub Button_Click_1(sender As Object, e As RoutedEventArgs)
        Dim contents As StringBuilder = New StringBuilder()
        Dim nextLine As String
        Dim lineCounter As Integer = 1

        Dim openPicker = New FileOpenPicker()
        openPicker.SuggestedStartLocation = PickerLocationId.DocumentsLibrary

        openPicker.FileTypeFilter.Add(".txt")
        Dim selectedFile As StorageFile = Await openPicker.PickSingleFileAsync()

        Using reader As StreamReader = New StreamReader(Await selectedFile.OpenStreamForReadAsync())
            nextLine = Await reader.ReadLineAsync()
            While (nextLine <> Nothing)
                contents.AppendFormat("{0}. ", lineCounter)
                contents.Append(nextLine)
                contents.AppendLine()
                lineCounter = lineCounter + 1
                If (lineCounter > 3) Then
                    contents.AppendLine("Only first 3 lines shown.")
                    Exit While
                End If
                nextLine = Await reader.ReadLineAsync()
            End While
        End Using
        DisplayContentsBlock.Text = contents.ToString()
    End Sub
End Class

<Page
    x:Class="ExampleApplication.BlankPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:ExampleApplication"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">

    <StackPanel Background="{StaticResource ApplicationPageBackgroundBrush}" VerticalAlignment="Center" HorizontalAlignment="Center">
        <TextBlock Text="Display lines from a file."></TextBlock>
        <Button Content="Load File" Click="Button_Click_1"></Button>
        <TextBlock Name="DisplayContentsBlock"></TextBlock>
    </StackPanel>
</Page>

Stream
E/S de archivos y secuencias
Programación asincrónica con Async y Await

Mostrar: