Главная » C# » Асинхронный подход в Visual C# (Sharp)

0

При асинхронном подходе наш код начинает исполнение задачи, например чтение файла или получение записи базы данных, но вместо того, чтобы ожидать резулаты, предоставляет их получение и последующую обработку другому коду. Асиронное взаимодействие является частным случаем архитектуры "постаик/потребитель", только  подробности поставщика скрыты. Задача запуска поставщика и предоставления потребителя возлагается на разработчика.

Асинхронная методика, используемая во всем интерфейсе API .NET, характеризтся постоянством и легко демонстрируется посредством асинхронного чтения файла. В главе 10 было рассмотрено чтения файла или консоли посредством сиронных методов. С таким же эффектом чтение файла или потока можно было бы выполнить асинхронно.

Асинхронный подход применяется, когда мы не хотим ожидать завершения волнения задачи.  Например,  представьте,  что загрузка файла занимает  15  секунд, в течение которых мы ничего не делаем, а просто ожидаем окончания загрузки. Пятнадцать секунд может показаться не таким уж и долгим ожиданием, но с точки зрения пользовательского интерфейса это довольно длительный период времени. Если на протяжении этих 15 секунд приложение не реагирует на действия пользателя, то вряд ли он получит от этого удовольствие.

Асинхронное чтение файла можно выполнить с помощью следующего кода:

FileStream fs = new FileStream(filename, FileMode.Open); Byte[] data = new byte[200000];

IAsyncResult asyncResult = fs.BeginRead(data, 0, data.Length, (lambdaAsync) => {

FileStream localFS = (FileStream) lambdaAsync .AsyncState,- int bytesRead = localFS.EndRead(lambdaAsync);

string buffer = System.Text.ASCIIEncoding.ASCII.GetString(data); Console. WriteLine( "Buffer bytes read (" + bytesRead + "*)");

localFS.CloseO ;

}, fs); asyncResult.AsyncWaitHandle.WaitOne();

В первом фрагменте кода выполняется инициализация процесса чтения файла, а во втором — обработка прочитанной информации.

Фрагмент для чтения файла состоит из следующего кода: FileStream fs = new FileStream(filename, FileMode.Open); Byte[] data = new byte[200000];

IAsyncResult asyncResult = fs.BeginRead(data, 0, data.Length, (lambdaAsync) => {

},fs);

asyncResult.AsyncWaitHandle.WaitOne();

Как и в примерах в главе 10, для чтения файла необходимо открыть файловый пок. Но вместо того чтобы считывать данные напрямую, вызывается  метод BeginRead (), который запускает операцию чтения. Но асинхронная операция отлается тем, что метод BeginRead () сразу же возвращает управление. Это можно рассматривать как запуск поставщика.

Первые три параметра, передаваемые методу BeginRead (), представляют перемеую,  содержащую  прочитанные  байты.  Первый  параметр —  это  массив  байтов, в который следует записывать данные. Второй и третий параметры представляют начальную и конечную позиции в массиве байтов для операции записи. Четвертым параметром метода BeginRead () является делегат, который вызывается, когда даые готовы для обработки. Последний параметр похож на параметр потока и прваивается члену данных IAsyncResult.AsyncState. Интерфейс IAsyncResult находится в пространстве имен System и  поэтому  является  частью  интерфейса API .NET.

Вызывая метод BeginReadO, мы говорим: "Заполни массив байтов наибольшим возможным числом байтов. Считав байты, вызови код потребителя, который опрелен в виде лямбда-выражения". Заполнение массива и вызов кода потребителя происходит в отдельном потоке.

Метод AsyncWaitHandle.waitone() вызывается с целью иллюстрации, чтобы иолнение главного вызывающего потока продолжалось только после того, как даые были считаны и обработаны. Это лишний вызов метода, т. к. он заставляет операцию чтения файла выглядеть подобно синхронной операции.

Прочитанная информация обрабатывается следующим кодом: FileStream localFS = (FileStream)lambdaAsync.AsyncState; int bytesRead = localFS.EndRead(lambdaAsync);

string buffer = System.Text.ASCIIEncoding.ASCII.GetString(data);

Console.WriteLine^"Buffer bytes read (" + bytesRead + ")"); localFS.CloseO ;

Код потребителя выполняется в отдельном потоке и является ответственным за считывание  всех байтов.  Код  преобразует член данных Asyncstate  в  Filestrea m и считывает оставшиеся байты с потока. После этого поток байтов преобразовываея в строку. Когда все данные считаны, файловый поток закрывается.

При использовании асинхронного подхода мы в действительности создаем код птавщика/потребителя. Использование интерфейса iAsyncResult и методов BeginReadO и EndReadO является довольно распространенным при этом подходе. Целью  асинхронного  интерфейса  является  преобразование  синхронной  операции в асинхронную.

Источник: Гросс  К. С# 2008:  Пер. с англ. — СПб.:  БХВ-Петербург, 2009. — 576 е.:  ил. — (Самоучитель)

По теме:

  • Комментарии