Použití modifikátoru Async pro přístup k souborům (C# a Visual Basic)
Můžete použít asynchronní funkce pro přístup k souborům.Pomocí funkce asynchronní můžete volat na asynchronní metody bez pomocí zpětných volání nebo rozdělení kódu více metod nebo lambda výrazů.Chcete-li kód synchronní asynchronní, stačí volání asynchronní metody namísto synchronní metody a kódu přidat několik klíčových slov.
Zvažte následující důvody pro přidání asynchrony do souboru access volání:
Asynchrony je uživatelské rozhraní aplikace reagovat rychleji protože uživatelské rozhraní, která spouští operace lze provádět jinou práci.Uživatelské rozhraní musí spustit kód uživatelského rozhraní může zmrazit, dokud je I/O a uživatelské rozhraní znovu zpracovat klávesnice a myš vstupní a jiných akcí, který trvá dlouho (například více než 50 milisekund).
Asynchrony snížení potřeby podprocesů zlepšuje škálovatelnost ASP a serverové aplikace.Pokud aplikace používá vyhrazenou podprocesu na odpověď a tisíce požadavků jsou právě zpracovávány současně, je třeba tisíce podprocesů.Asynchronní operace často není třeba použít během čekání podprocesu.Na konci krátce používají existující dokončení podprocesem.
Zpoždění operace přístupu souboru může být za současných podmínek velmi nízké, ale latence může výrazně zvýšit v budoucnu.Například soubor přesunut na server, který je po celém světě.
Přidané režii asynchronní funkce je malá.
Asynchronní úlohy lze snadno spustit současně.
Spuštění příkladů
[!POZNÁMKA]
Příklady v tomto tématu se nevztahují na Windows Store aplikacím, které jsou Windows 8 aplikace, které jsou na celé obrazovce a přizpůsobený pro dotykové interakce.Informace o použití souboru access asynchronní v Windows Store apps, viz .NET for Windows Store apps overview a Soubor a proud vstupy.Příklady souborového I/O pro Windows Store apps, můžete stáhnout Přístup ukázkový soubor.
Spustit v příkladech v tomto tématu, můžete vytvořit Aplikací WPF nebo Model Windows Forms aplikace a přidejte tlačítko.Na tlačítku Click událostí, v každém případě přidat volání metody první.
V následujících příkladech patří Imports (Visual Basic) nebo using příkazy (C#).
Imports System
Imports System.Collections.Generic
Imports System.Diagnostics
Imports System.IO
Imports System.Text
Imports System.Threading.Tasks
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Text;
using System.Threading.Tasks;
Použití třídy FileStream
Příklady v tomto tématu FileStream třídy, která má možnost, která způsobuje asynchronního I/O dochází na úrovni operačního systému.Pomocí této možnosti můžete zabránit blokování podproces fondu podprocesů v mnoha případech.Chcete-li tuto možnost, zadejte useAsync=true nebo options=FileOptions.Asynchronous argument ve volání konstruktoru.
Nelze použít tuto možnost s StreamReader a StreamWriter otevřete přímo zadáním cesty k souboru.Však můžete použít tuto možnost, pokud jim poskytnout Stream , FileStream otevření třídy.Všimněte si, že asynchronní volání rychlejší v uživatelském rozhraní aplikace i v případě, že podproces fondu podprocesů je blokován, protože během čekání není blokován uživatelské rozhraní.
Psaní textu
Následující příklad zapíše do souboru text.Na každém vyčkání prohlášení, metoda okamžitě ukončí.Po dokončení soubor I/O metoda obnoví na příkazu následujícím příkazem await.Všimněte si, že je asynchronní modifikátor definice metody používající příkaz 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
public async void ProcessWrite()
{
string filePath = @"temp2.txt";
string text = "Hello World\r\n";
await WriteTextAsync(filePath, text);
}
private async Task WriteTextAsync(string filePath, string text)
{
byte[] encodedText = Encoding.Unicode.GetBytes(text);
using (FileStream sourceStream = new FileStream(filePath,
FileMode.Append, FileAccess.Write, FileShare.None,
bufferSize: 4096, useAsync: true))
{
await sourceStream.WriteAsync(encodedText, 0, encodedText.Length);
};
}
Původní příkladu má příkaz await sourceStream.WriteAsync(encodedText, 0, encodedText.Length);, což je snížení následující dva příkazy:
Dim theTask As Task = sourceStream.WriteAsync(encodedText, 0, encodedText.Length)
Await theTask
Task theTask = sourceStream.WriteAsync(encodedText, 0, encodedText.Length);
await theTask;
První příkaz vrátí úkolu a způsobí zpracování souboru spustit.S await druhý příkaz způsobí, že metoda okamžitě ukončit a vrátit jiný úkol.Po dokončení zpracování později souboru spuštění vrátí příkaz, který následuje await.Další informace naleznete v tématu Řízení toku v programech asynchronní (C# a Visual Basic) a Postupy: Použití ladicího programu u asynchronních metod.
Čtení textu
Následující příklad načte text ze souboru.Text je do vyrovnávací paměti a v tomto případě umístěn do StringBuilder.Na rozdíl od předchozího příkladu vytváří hodnocení await hodnotu.ReadAsync Metoda vrátí Task<Int32>, takže vznikne hodnocení await Int32 hodnoty (numRead) po dokončení operace.Další informace naleznete v tématu Typy vrácení asynchronní (C# a 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
public async void ProcessRead()
{
string filePath = @"temp2.txt";
if (File.Exists(filePath) == false)
{
Debug.WriteLine("file not found: " + filePath);
}
else
{
try
{
string text = await ReadTextAsync(filePath);
Debug.WriteLine(text);
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message);
}
}
}
private async Task<string> ReadTextAsync(string filePath)
{
using (FileStream sourceStream = new FileStream(filePath,
FileMode.Open, FileAccess.Read, FileShare.Read,
bufferSize: 4096, useAsync: true))
{
StringBuilder sb = new StringBuilder();
byte[] buffer = new byte[0x1000];
int numRead;
while ((numRead = await sourceStream.ReadAsync(buffer, 0, buffer.Length)) != 0)
{
string text = Encoding.Unicode.GetString(buffer, 0, numRead);
sb.Append(text);
}
return sb.ToString();
}
}
Paralelní asynchronního I/O
Následující příklad ukazuje paralelní zpracování zápisem 10 textových souborů.Pro každý soubor WriteAsync metoda vrátí úkol, který je potom přidán do seznamu úkolů.await Task.WhenAll(tasks); Příkaz ukončí metody a životopisy v rámci metody zpracování souboru po dokončení pro všechny úkoly.
Příklad Zavře všechna FileStream instance v finally blokovat po dokončení úkolů.Pokud každý FileStream místo toho byl vytvořen v using prohlášení, FileStream může být zneškodněny před dokončením úkolu.
Všimněte si, že jakékoli zvýšení výkonu téměř výhradně z paralelní zpracování a nikoli asynchronního zpracování.Výhody asynchrony se, že není poutat více podprocesů a že není poutat podproces uživatelského rozhraní.
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
public async void ProcessWriteMult()
{
string folder = @"tempfolder\";
List<Task> tasks = new List<Task>();
List<FileStream> sourceStreams = new List<FileStream>();
try
{
for (int index = 1; index <= 10; index++)
{
string text = "In file " + index.ToString() + "\r\n";
string fileName = "thefile" + index.ToString("00") + ".txt";
string filePath = folder + fileName;
byte[] encodedText = Encoding.Unicode.GetBytes(text);
FileStream sourceStream = new FileStream(filePath,
FileMode.Append, FileAccess.Write, FileShare.None,
bufferSize: 4096, useAsync: true);
Task theTask = sourceStream.WriteAsync(encodedText, 0, encodedText.Length);
sourceStreams.Add(sourceStream);
tasks.Add(theTask);
}
await Task.WhenAll(tasks);
}
finally
{
foreach (FileStream sourceStream in sourceStreams)
{
sourceStream.Close();
}
}
}
Při použití WriteAsync a ReadAsync metod, můžete zadat CancellationToken, který můžete použít ke zrušení operace mid-stream.Další informace naleznete v tématu Vyladění aplikace s modifikátorem Async (C# a Visual Basic) a Zrušení ve spravovaných podprocesů.
Viz také
Úkoly
Postupy: Použití ladicího programu u asynchronních metod
Koncepty
Asynchronní asynchronní pro programování a očekávat (C# a Visual Basic)