» » » » Язык программирования 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.

Перейти на страницу:
class="code">  var task2=Task.Run(() =>

  {

    Thread.Sleep(1_000);

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

  });

    var task3 = Task.Run(() =>

  {

    Thread.Sleep(1_000);

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

  });

  await Task.WhenAll(task1, task2, task3);

}

Запустив программу, вы увидите, что три задачи запускаются в порядке от наименьшего значения, указанного при вызове метода Sleep():

Fun With Async ===>

Done with work!

Void method completed

Done with second task!

Done with third task!

Done with first task!

Completed

Существует также метод WhenAnу(), возвращающий задачу, которая завершилась. Для демонстрации работы WhenAny() измените последнюю строку метода MultipleAwaits() следующим образом:

await Task.WhenAny(task1, task2, task3);

В результате вывод становится таким:

Fun With Async ===>

Done with work!

Void method completed

Done with second task!

Completed

Done with third task!

Done with first task!

Вызов асинхронных методов из неасинхронных методов

В каждом из предшествующих примеров ключевое слово async использовалось для возвращения в поток вызывающего кода, пока выполняется асинхронный метод. В целом ключевое слово await может применяться только в методе, помеченном как async. А что если вы не можете (или не хотите) помечать метод с помощью async?

К счастью, существуют другие способы вызова асинхронных методов. Если вы просто не используете ключевое слово await, тогда код продолжает работу после асинхронного метода, не возвращая управление вызывающему коду. Если вам необходимо ожидать завершения асинхронного метода (что происходит, когда применяется ключевое слово await), то существуют два подхода.

Первый подход предусматривает просто использование свойства Result с методами, возвращающими Task<T>, или метода Wait() с методами, возвращающими Task/Task<T>. (Вспомните, что метод, который возвращает значение, обязан возвращать Task<T>, будучи асинхронным, а метод, не имеющий возвращаемого значения, возвращает Task, когда является асинхронным.) Если метод терпит неудачу, то возвращается AggregateException.

Можете также добавить вызов GetAwaiter().GetResult(), который обеспечивает такой же эффект, как ключевое слово await в асинхронном методе, и распространяет исключения в той же манере, что и async/await. Тем не менее, указанные методы помечены в документации как "не предназначенные для внешнего использования", а это значит, что они могут измениться либо вовсе исчезнуть в какой-то момент в будущем. Вызов GetAwaiter().GetResult() работает как с методами, возвращающими значение, так и с методами без возвращаемого значения.

На заметку! Решение использовать свойство Result или вызов GetAwaiter().GetResult() с Task<T> возлагается полностью на вас, и большинство разработчиков принимают решение, основываясь на обработке исключений. Если ваш метод возвращает Task, тогда вы должны применять вызов GetAwaiter().GetResult() или Wait().

Например, вот как вы могли бы вызывать метод DoWorkAsync():

Console.WriteLine(DoWorkAsync().Result);

Console.WriteLine(DoWorkAsync().GetAwaiter().GetResult());

Чтобы остановить выполнение до тех пор, пока не произойдет возврат из метода с возвращаемым типом void, просто вызовите метод Wait() на объекте Task:

MethodReturningVoidAsync().Wait();

Ожидание с помощью await в блоках catch и finally

 В версии C# 6 появилась возможность помещения вызовов await в блоки catch и finally. Для этого сам метод обязан быть async. Указанная возможность демонстрируется в следующем примере кода:

static async Task<string> MethodWithTryCatch()

{

  try

  {

    //Do some work

    return "Hello";

  }

  catch (Exception ex)

  {

    await LogTheErrors();

    throw;

  }

  finally

  {

    await DoMagicCleanUp();

  }

}

Обобщенные возвращаемые типы в асинхронных методах (нововведение в версии 7.0)

До выхода версии C# 7 возвращаемыми типами методов async были только Task, Task<T> и void. В версии C# 7 доступны дополнительные возвращаемые типы при условии, что они следуют шаблону с ключевым словом async. В качестве конкретного примера можно назвать тип ValueTask. Введите код, подобный показанному ниже:

static async ValueTask<int> ReturnAnInt()

{

  await Task.Delay(1_000);

  return 5;

}

К типу ValueTask применимы все те же самые правила, что и к типу Task, поскольку ValueTask — это просто объект Task для типов значений, заменяющий собой принудительное размещение объекта в куче.

Локальные функции (нововведение в версии 7.0)

Локальные функции были представлены в главе 4 и использовались в главе 8 с итераторами. Они также могут оказаться полезными для асинхронных методов. Чтобы продемонстрировать преимущество, сначала нужно взглянуть на проблему. Добавьте новый метод по имени MethodWithProblems() со следующим кодом:

static async Task MethodWithProblems(int firstParam, int secondParam)

{

  Console.WriteLine("Enter");

  await Task.Run(() =>

  {

    // Вызвать длительно выполняющийся метод

    Thread.Sleep(4_000);

    Console.WriteLine("First Complete");

    // Вызвать еще один длительно выполняющийся метод, который терпит

    // неудачу из-за того, что значение второго параметра выходит

    // за пределы допустимого диапазона.

    Console.WriteLine("Something bad happened");

  });

}

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

static async Task MethodWithProblemsFixed(int firstParam, int secondParam)

{

  Console.WriteLine("Enter");

  if (secondParam < 0)

  {

    Console.WriteLine("Bad data");

    return;

  }

  await actualImplementation();

  async Task actualImplementation()

  {

    await Task.Run(() =>

    {

      // Вызвать длительно выполняющийся метод

      Thread.Sleep(4_000);

      Console.WriteLine("First Complete");

      // Вызвать еще один длительно выполняющийся метод, который терпит

      // неудачу из-за того, что значение

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