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 escritorio 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, ReadLineAsyncy ReadToEndAsync. Estos métodos asincrónicos se implementan en clases de secuencias, como Stream, FileStreamy 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 disponibles en las versiones actuales de .NET para admitir código heredado, pero los métodos asincrónicos facilitan la implementación de operaciones de E/S asincrónicas con más facilidad.
C# y Visual Basic tienen dos palabras clave para la programación asincrónica:
El modificadorAsync (Visual Basic) o async (C#), que se utiliza para marcar un método que contiene una operación asincrónica.
El operadorAwait (Visual Basic) o await (C#), que se aplica al resultado de un método asincrónico.
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.
C#
using System;
using System.Threading.Tasks;
using System.Windows;
using System.IO;
namespaceWpfApplication
{
publicpartialclassMainWindow : Window
{
publicMainWindow()
{
InitializeComponent();
}
privateasyncvoidButton_Click(object sender, RoutedEventArgs e)
{
string startDirectory = @"c:\Users\exampleuser\start";
string endDirectory = @"c:\Users\exampleuser\end";
foreach (string filename in Directory.EnumerateFiles(startDirectory))
{
using (FileStream sourceStream = File.Open(filename, FileMode.Open))
{
using (FileStream destinationStream = File.Create(Path.Combine(endDirectory, Path.GetFileName(filename))))
{
await sourceStream.CopyToAsync(destinationStream);
}
}
}
}
}
}
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(4095) 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.
C#
using System;
using System.IO;
using System.Text;
using Windows.Storage.Pickers;
using Windows.Storage;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
namespaceExampleApplication
{
publicsealedpartialclassBlankPage : Page
{
publicBlankPage()
{
this.InitializeComponent();
}
privateasyncvoidButton_Click_1(object sender, RoutedEventArgs e)
{
StringBuilder contents = new StringBuilder();
string nextLine;
int lineCounter = 1;
var openPicker = new FileOpenPicker();
openPicker.SuggestedStartLocation = PickerLocationId.DocumentsLibrary;
openPicker.FileTypeFilter.Add(".txt");
StorageFile selectedFile = await openPicker.PickSingleFileAsync();
using (StreamReader reader = new StreamReader(await selectedFile.OpenStreamForReadAsync()))
{
while ((nextLine = await reader.ReadLineAsync()) != null)
{
contents.AppendFormat("{0}. ", lineCounter);
contents.Append(nextLine);
contents.AppendLine();
lineCounter++;
if (lineCounter > 3)
{
contents.AppendLine("Only first 3 lines shown.");
break;
}
}
}
DisplayContentsBlock.Text = contents.ToString();
}
}
}
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
XAML
<Pagex: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"><StackPanelBackground="{StaticResource ApplicationPageBackgroundBrush}"VerticalAlignment="Center"HorizontalAlignment="Center"><TextBlockText="Display lines from a file."></TextBlock><ButtonContent="Load File"Click="Button_Click_1"></Button><TextBlockName="DisplayContentsBlock"></TextBlock></StackPanel></Page>
El origen de este contenido se puede encontrar en GitHub, donde también puede crear y revisar problemas y solicitudes de incorporación de cambios. Para más información, consulte nuestra guía para colaboradores.
Comentarios de .NET
.NET es un proyecto de código abierto. Seleccione un vínculo para proporcionar comentarios:
Únase a la serie de reuniones para crear soluciones de inteligencia artificial escalables basadas en casos de uso reales con compañeros desarrolladores y expertos.