» » » » Язык программирования C#9 и платформа .NET5 - Эндрю Троелсен

Язык программирования C#9 и платформа .NET5 - Эндрю Троелсен

На нашем литературном портале можно бесплатно читать книгу Язык программирования C#9 и платформа .NET5 - Эндрю Троелсен, Эндрю Троелсен . Жанр: Программирование. Онлайн библиотека дает возможность прочитать весь текст и даже без регистрации и СМС подтверждения на нашем литературном портале litmir.org.
Язык программирования C#9 и платформа .NET5 - Эндрю Троелсен
Название: Язык программирования C#9 и платформа .NET5
Дата добавления: 22 август 2024
Количество просмотров: 288
Читать онлайн

Внимание! Книга может содержать контент только для совершеннолетних. Для несовершеннолетних просмотр данного контента СТРОГО ЗАПРЕЩЕН! Если в книге присутствует наличие пропаганды ЛГБТ и другого, запрещенного контента - просьба написать на почту readbookfedya@gmail.com для удаления материала

Язык программирования C#9 и платформа .NET5 читать книгу онлайн

Язык программирования C#9 и платформа .NET5 - читать бесплатно онлайн , автор Эндрю Троелсен

В 10-м издании книги описаны новейшие возможности языка C# 9 и .NET 5 вместе с подробным "закулисным" обсуждением, призванным расширить навыки критического мышления разработчиков, когда речь идет об их ремесле.
Книга охватывает ASP.NET Core, Entity Framework Core и многое другое наряду с последними обновлениями унифицированной платформы .NET, начиная с улучшений показателей производительности настольных приложений Windows в .NET 5 и обновления инструментария XAML и заканчивая расширенным рассмотрением файлов данных и способов обработки данных.
Все примеры кода были переписаны с учетом возможностей последнего выпуска C# 9.

Перейти на страницу:
async/await в приложении WPF, то инфраструктура WPF обеспечит диспетчеризацию делегата и обратный вызов в конечном автомате при завершении ожидающей задачи, чтобы безопасным образом обновить элементы управления.

Роль метода ConfigureAwait()

Теперь, когда вы лучше понимаете роль класса SynchronizationContext, пришло время раскрыть роль метода ConfigureAwait(). По умолчанию применение await к объекту Task приводит к использованию контекста синхронизации. При разработке приложений с графическим пользовательским интерфейсом (Windows Forms, WPF) именно такое поведение является желательным. Однако в случае написания кода приложения без графического пользовательского интерфейса накладные расходы, связанные с постановкой в очередь исходного контекста, когда в этом нет нужды, потенциально могут вызвать проблемы с производительностью приложения.

Чтобы увидеть все в действии, модифицируйте операторы верхнего уровня, как показано ниже:

Console.WriteLine(" Fun With Async ===>");

// Console.WriteLine(DoWork());

string message = await DoWorkAsync();

Console.WriteLine(message);

string message1 = await DoWorkAsync().ConfigureAwait(false);

Console.WriteLine(message1);

В исходном блоке кода применяется класс SynchronizationContext, поставляемый инфраструктурой (в данном случае средой .NET Core Runtime), что эквивалентно вызову ConfigureAwait(true). Во втором примере текущий контекст и планировщик игнорируются.

Согласно рекомендациям команды создателей .NET Core при разработке прикладного кода (Windows Forms, WPF и т.д.) следует полагаться на стандартное поведение, а в случае написания неприкладного кода (скажем, библиотеки) использовать вызов ConfigureAwait(false). Одним исключением является инфраструктура ASP.NET Core (рассматриваемая в части IX), где специальная реализация SynchronizationContext не создается; таким образом, вызов ConfigureAwait(false) не дает преимущества при работе с другими инфраструктурами. 

Соглашения об именовании асинхронных методов

Конечно же, вы заметили, что мы изменили имя метода с DoWork() на DoWorkAsync(), но по какой причине? Давайте предположим, что новая версия метода по-прежнему называется DoWork(), но вызывающий код реализован так:

// Отсутствует ключевое слово await!

string message = DoWork();

Обратите внимание, что мы действительно пометили метод ключевым словом async, но не указали ключевое слово await при вызове DoWork(). Здесь мы получим ошибки на этапе компиляции, потому что возвращаемым значением DoWork() является объект Task, который мы пытаемся напрямую присвоить переменной типа string. Вспомните, что ключевое слово await отвечает за извлечение внутреннего возвращаемого значения, которое содержится в объекте Task. Поскольку await отсутствует, возникает несоответствие типов.

На заметку! Метод, поддерживающий await — это просто метод, который возвращает Task или Task<T>.

С учетом того, что методы, которые возвращают объекты Task, теперь могут вызываться в неблокирующей манере посредством конструкций async и await, в Microsoft рекомендуют (в качестве установившейся практики) снабжать имя любого метода, возвращающего Task, суффиксом Async. В таком случае разработчики, которым известно данное соглашение об именовании, получают визуальное напоминание о том, что ключевое слово await является обязательным, если они намерены вызывать метод внутри асинхронного контекста.

На заметку! Обработчики событий для элементов управления графического пользовательского интерфейса (вроде обработчика события Click кнопки), а также методы действий внутри приложений в стиле MVC, к которым применяются ключевые слова async и await, не следуют указанному соглашению об именовании.

Асинхронные методы, возвращающие void

В настоящий момент наш метод DoWorkAsync() возвращает объект Task, содержащий "реальные данные" для вызывающего кода, которые будут получены прозрачным образом через ключевое слово await. Однако что если требуется построить асинхронный метод, возвращающий void? Реализация зависит о того, нуждается метод в применении await или нет (как в сценариях "запустил и забыл").

Асинхронные методы, возвращающие void и поддерживающие await

Если асинхронный метод должен поддерживать await, тогда используйте необобщенный класс Task и опустите любые операторы return, например:

static async Task MethodReturningTaskOfVoidAsync()

{

  await Task.Run(() => { /*  Выполнить какую-то работу... */

                         Thread.Sleep(4_000);

                       });

  Console.WriteLine("Void method completed");

                  // Метод завершен

}

Затем в коде, вызывающем этот метод, примените ключевое слово await:

MethodReturningVoidAsync();

Console.WriteLine("Void method complete");

Асинхронные методы, возвращающие void и работающие в стиле "запустил и забыл"

 Если метод должен быть асинхронным, но не обязан поддерживать await и применяться в сценариях "запустил и забыл", тогда добавьте ключевое слово async и сделайте возвращаемым типом void, а не Task. Методы такого рода обычно используются для задач вроде ведения журнала, когда нежелательно, чтобы запись в журнал приводила к задержке выполнения остального кода.

static async void MethodReturningVoidAsync()

{

  await Task.Run(() => { /* Выполнить какую-то работу... */

                         Thread.Sleep(4_000);

                       });

  Console.WriteLine("Fire and forget void method completed");

                  // Метод завершен

}

Затем в коде, вызывающем этот метод, ключевое слово await не используется:

MethodReturningVoidAsync();

Console.WriteLine("Void method complete");

Асинхронные методы с множеством контекстов await

Внутри реализации асинхронного метода разрешено иметь множество контекстов await. Следующий код является вполне допустимым:

static async Task MultipleAwaits()

{

    await Task.Run(() => { Thread.Sleep(2_000); });

    Console.WriteLine("Done with first task!");

                    // Первая задача завершена!

    await Task.Run(() => { Thread.Sleep(2_000); });

    Console.WriteLine("Done with second task!");

                    // Вторая задача завершена!

    await Task.Run(() => { Thread.Sleep(2_000); });

    Console.WriteLine("Done with third task!");

                    // Третья задача завершена!

}

Здесь каждая задача всего лишь приостанавливает текущий поток на некоторый период времени; тем не менее, посредством таких задач может быть представлена любая единица работы (обращение к веб-службе, чтение базы данных или что-нибудь еще). Еще один вариант предусматривает ожидание не каждой отдельной задачи, а всех их вместе. Это более вероятный сценарий, когда имеются три работы (скажем, проверка поступления сообщений электронной почты, обновление сервера, загрузка файлов), которые должны делаться в пакете, но могут выполняться параллельно. Ниже приведен модифицированный код, в котором используется метод Task.WhenAll():

static async Task MultipleAwaits()

{

  var task1 = Task.Run(() =>

  {

    Thread.Sleep(2_000);

    Console.WriteLine("Done with first task!");

  });

Перейти на страницу:
Комментариев (0)