асинхронное-программирование--в-погоне-за-идеалом-.-часть-1

Асинхронное программирование: В погоне за идеалом . Часть 1

На языке C# присутствует много видов использoвания многопоточности (concurrent). В этих и последующих постах речь будет идти oб асинхронном программировании.

Асинхронное программирование заключается в том, что результат выполнения функции доступен не сразу, а через некоторое время в виде некоторого асинхронного вызова.

Первым API Асинхронности на языке C# был так называемый APM(Asynchronous Programming Model/Асинхронная модель программирования).

Этот старый модель для асинхронного программирования использует шаблон проектирование IAsyncResult. В некоторых библиотеках .NЕТ мы встречаем методы BeginXXX(BeginOperationName) и EndXXX(EndOperationName)  эти методы вместе помогает нам использовать APM.

static void Main(string[] args)
       {

            FileStream fs = new FileStream("Sdfsf", FileMode.Open);

            byte[] array = new byte[fs.Length];

            //start async operation and return handle.. line 17...
          IAsyncResult asyncResult = fs.BeginRead(array,0, (int)fs.Length, null, null);

            //emulating some other operations
            Thread.Sleep(1000);

            //wait here if operation already not completed
            fs.EndRead(asyncResult);

        }

Разница между асинхронным и многопоточным программированием заключается в том что Асинхронные методы предназначены для неблокируемых операций. Мы используем асинхронное программирование когда нам нужна работа с устройствами ввода и вывода. Это когда мы работаем с базами данных, различными файлами или с сетью.

APM в этом ситуации не является исключением.

               Итак, давайте изучим как работает наш код. Hа строке BeginRead() мы асинхронно вызываем чтение файла. При этом наш основной поток неблокируется! Дело в том что когда мы вызываем что- то асинхронно то запрос посылается обработчику аппарата-устройства. В нашем ситуации это файловая система OС, и нам не важно как будет обрабатываться запрос. Мы отправили команду и не ожидая его, продолжаем работать в нашем основном потоке.

Видно что наш основной поток пока не занят этой работой. Но мы должны как-то получать ответ. Нам нужен какой-то handle-descriptor, роль этого дескриптора играет IAsyncResult, после вызова BeginRead() метод моментально возвращает IAsyncResult и продолжает работу. До вызова EndRead() наш метод (в этой ситуации BeginRead ) продолжает работать асинхронно. Метод EndRead() принуждает наш основной поток останавливать и ждать результата выполнения асинхронного метода. Если до вызова EndRead() асинхронный метод закончит работу тогда не будет никакой задержки и программа нормально продолжит работу.

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

        Func<decimal, decimal, decimal> func = (x, y) =>

            {

                //enumating some big operation here..

                Thread.Sleep(2000);

                return x * y;

            };

           IAsyncResult delAsyncResult = func.BeginInvoke(45, 67, null, null);

            //emulating some other operations
            Thread.Sleep(1000);

            //wait here and get result
           decimal result = func.EndInvoke(delAsyncResult);
Асинхронные делегаты позволяют вызывать методы, на которые эти делегаты указывают, в асинхронном режиме.

Метод BeginInvoke в нашем ситуации принимает, 4 параметра. Первые две аргумента понятно. Третий параметр представляет делегат System.AsyncCallback. AsyncCallback указывает на метод, который будет выполняться в результате завершения работы асинхронного делегата. В данном случае мы игнорируем его и на его место передаем значение null.

4-ый параметр представляет объект, с помощью которого мы можем передать дополнительную информацию в метод завершения, указанный в предыдущем параметре. Этот объект хранит информацию об асинхронной операции. Затем этот объект передаем в метод EndInvoke и получаем результат.


 static void Main(string[] args)
        {
       
            Func<decimal, decimal, decimal> func = (x, y) =>
            {
                //enumating some big operation here..
                Thread.Sleep(2000);
                return x * y;
            };


           IAsyncResult delAsyncResult = func.BeginInvoke(45, 67, MyCallBack, "operation completed successfully");


            //emulating some other operations
            Thread.Sleep(1000);


            //wait here and get result
           decimal result = func.EndInvoke(delAsyncResult);
            Console.ReadLine();


        }


        private static void MyCallBack(IAsyncResult ar)
        {
            string message =  ar.AsyncState.ToString();
            Console.WriteLine(message);
        }


Tural

Tural Süleymani

Süleymani Tural Microsoft-un MCSD statuslu mütəxəssisidir, 2008-ci ildən bu yana proqramlaşdırma üzrə tədris aparır

последние посты автора на этом языке

вам возможно понравится эти посты