Поделиться через


Использование метода Async для доступа к файлам (C# и Visual Basic)

Можно использовать функцию Async для доступа к файлам.Async с помощью функции можно вызывать асинхронные методы без использования обратных вызовов или разделить ваш код через несколько методов или лямбда-выражения.Для выполнения параллельной асинхронного кода, просто вызовите асинхронный метод вместо синхронного метода и добавить несколько ключевых слов к коду.

Можно рассмотреть следующие причины для добавления asynchrony вызовов доступа к файлу.

  • Asynchrony делает приложения пользовательского интерфейса, отзывчивым поскольку поток пользовательского интерфейса, который начинается операция может выполнять другую работу.Если поток пользовательского интерфейса должен выполнять код, который занимает много времени (например, более 50 миллисекунд), пользовательский интерфейс может приостановить до тех пор, пока не будет завершен и ВВОДА-ВЫВОДА поток пользовательского интерфейса может снова обработка ввода с клавиатуры и мыши и других событий.

  • Asynchrony повышает масштабируемость ASP.NET и других серверных приложений за счет уменьшения необходимости использования потоков.Если приложение использует выделенный поток в ответ и регулируются каждую тысячу запросов одновременно, каждую тысячу потоков не требуются.Асинхронным операциям, часто не будет использоваться поток во время ожидания.Они используют существующий поток завершения ВВОДА-ВЫВОДА кратко в конце.

  • Задержка операции доступа к файлу может быть очень низкими нижними текущий условиях, но задержка может значительно увеличить в будущем.Например, файл может быть переместить на сервер, через world.

  • Добавленные издержки использования функции Async мал.

  • Асинхронные задачи можно легко выполнить параллельно.

Запустить примеры

ПримечаниеПримечание

Примеры в этом разделе не применяются к Магазина Windows приложения, являющиеся приложениями, которые Windows 8 во весь экран и портняжничанный для взаимодействия с сенсорного ввода.Дополнительные сведения об использовании доступ к файлам async в приложениях Магазина Windows см. в разделе Обзор приложений .NET для Магазина Windows и Файловый и потоковый ввод-вывод.Примеры ФАЙЛОВОГО ввода-вывода для приложений Магазина Windows можно загрузить Храните образца доступа.

Чтобы выполнить примеры в этом разделе, можно создать Приложение WPF или Приложение Windows Forms, а затем добавлять Кнопка.В событии Click кнопки, добавьте вызов к первому методу в каждом примере.

В следующих примерах включите следующие Imports (Visual Basic) или формулировки using (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;

Использование класса FileStream

Примеры в этом подразделе используют класс FileStream, который содержит параметр, который вызывает АСИНХРОННЫЙ ввод-вывод происходить на уровне операционной системы.С помощью этого параметра можно избежать блокирование поток пула потоков во многих случаях.Чтобы включить этот параметр указывается аргумент useAsync=true или options=FileOptions.Asynchronous в вызове конструктора.

Этот параметр нельзя использовать с StreamReader и StreamWriter если открыть их, указав путь к файлу.Однако можно использовать этот параметр, если необходимо предоставить им Stream, класс FileStream открыл.Обратите внимание, что асинхронные вызовы выполняются быстрее в приложениях пользовательского интерфейса, даже если поток пула потоков отключить, поскольку поток пользовательского интерфейса не отключить во время ожидания.

Запись текста

Следующие примеры СМС вставке записи в файл.На каждом подождите выписки метод немедленно ".После завершения ВВОДА-ВЫВОДА файла, метод возобновляет на выписке, которая следует за выпиской ожидания.Обратите внимание, что модификатор async в определении методов, использующих выписку ожидания.

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);
    };
}

Исходный примере имеет выписку await sourceStream.WriteAsync(encodedText, 0, encodedText.Length);, сужение следующих 2 выписок:

Dim theTask As Task = sourceStream.WriteAsync(encodedText, 0, encodedText.Length)
Await theTask
Task theTask = sourceStream.WriteAsync(encodedText, 0, encodedText.Length);
await theTask;

Первая оператор возвращает задачу и вызывает запуск обработки файла.Вторая выписка с ожидания вызывает метод немедленно оставить и возвращает другую задачу.При обработке файла более поздних выполнение завершается, возвращается к выписке, которая следует за ожидания.Дополнительные сведения см. в разделах Поток управления в асинхронных программах (C# и Visual Basic) и Пошаговое руководство. Использование отладчика с асинхронными методами.

Чтение текста

В следующем примере выполняется чтение текста из файла.Текст с буферизацией) и в этом случае помещается в StringBuilder.В отличие от предыдущего примера оценка ожидания создает значение.Метод ReadAsync возвращает Task<Int32>, поэтому вычисление ожидания приводит значение Int32 (numRead) после завершения операции.Дополнительные сведения см. в разделе Асинхронные типы возвращаемых значений (C# и 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();
    }
}

Параллельный АСИНХРОННЫЙ ввод-вывод

В следующем примере показана параллельная обработка путем написания 10 текстовых файлов.Для каждого файла, метод WriteAsync получает задачу, затем добавлена в список задач.Оператор " await Task.WhenAll(tasks); метод и продолжает в методе завершения при обработке файла для всех задач.

Пример закрыть все экземпляры FileStream в блоке finally после завершения задачи.Если каждое FileStream, а не было создано в выписке using, то FileStream может быть удалено, прежде чем задача была завершена.

Обратите внимание, что любое digital производительности почти полностью от параллельной, а не асинхронной обработки.Преимущества asynchrony, что он не передает поиск нескольких потоков и не сообщает вверх поток пользовательского интерфейса.

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();
        }
    }
}

При использовании методов WriteAsync и ReadAsync, можно указать CancellationToken, который можно использовать для отмены средний- потоке операции.Дополнительные сведения см. в разделах Настройка асинхронного приложения (C# и Visual Basic) и Отмена в управляемых потоках.

См. также

Задачи

Пошаговое руководство. Использование отладчика с асинхронными методами

Основные понятия

Асинхронное программирование с использованием ключевых слов Async и Await (C# и Visual Basic)

Асинхронные типы возвращаемых значений (C# и Visual Basic)

Поток управления в асинхронных программах (C# и Visual Basic)