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

Шрифт:

-
+

Интервал:

-
+

Закладка:

Сделать
1 ... 292 293 294 295 296 297 298 299 300 ... 642

using System;

using System.Collections.Generic;

using System.Threading;

using System.Threading.Tasks;

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

Console.WriteLine(DoWork());

Console.WriteLine("Completed");

Console.ReadLine();

static string DoWork()

{

  Thread.Sleep(5_000);

  return "Done with work!";

}

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

Если бы мы решили прибегнуть к одному из описанных ранее приемов, чтобы сделать приложение более отзывчивым, тогда пришлось бы немало потрудиться. Тем не менее, начиная с версии .NET 4.5, можно написать следующий код С#:

...

string message = await DoWorkAsync();

Console.WriteLine(message);

...

static string DoWork()

{

  Thread.Sleep(5_000);

  return "Done with work!";

}

static <b>async Task</b>&lt;string&gt; DoWorkAsync()

{

  return <b>await</b> Task.Run(() =&gt;

  {

    Thread.Sleep(5_000);

    return &quot;Done with work!&quot;;

  });

}

Если вы используете в качестве точки входа метод Main() (вместо операторов верхнего уровня), тогда должны пометить метод с помощью ключевого слова async, появившегося в версии C# 7.1:

static <b>async</b> Task Main(string[] args)

{

  ...

  string message = await DoWorkAsync();

  Conole.WriteLine(message);

  ...

}

На заметку! Возможность декорирования метода Main() посредством async — нововведение, появившееся в версии C# 7.1. Операторы верхнего уровня в версии C# 9.0 являются неявно асинхронными.

Обратите внимание на ключевое слово await перед именем метода, который будет вызван в неблокирующей манере. Это важно: если метод декорируется ключевым словом async, но не имеет хотя бы одного внутреннего вызова метода с использованием await, то получится синхронный вызов (на самом деле компилятор выдаст соответствующее предупреждение).

(window.adrunTag = window.adrunTag || []).push({v: 1, el: 'adrun-4-390', c: 4, b: 390})

Кроме того, вы должны применять класс Task из пространства имен System.Threading.Tasks для переделки методов Main() (если вы используете Main()) и DoWork() (последний добавляется как DoWorkAsync()). По существу вместо возвращения просто специфического значения (объекта string в текущем примере) возвращается объект Task&lt;T&gt;, где обобщенный параметр типа Т представляет собой действительное возвращаемое значение.

Реализация метода DoWorkAsync() теперь напрямую возвращает объект Task&lt;T&gt;, который является возвращаемым значением Task.Run(). Метод Run() принимает делегат Func&lt;&gt; или Action&lt;&gt; и, как вам уже известно, для простоты здесь можно использовать лямбда-выражение. В целом новая версия DoWorkAsync() может быть описана следующим образом.

При вызове запускается новая задача, которая заставляет вызывающий поток уснуть на пять секунд. После завершения вызывающий поток предоставляет строковое возвращаемое значение. Эта строка помещается в новый объект Task&lt;string&gt; и возвращается вызывающему коду.

Благодаря новой реализации метода DoWorkAsync() мы можем получить некоторое представление о подлинной роли ключевого слова await. Оно всегда будет модифицировать метод, который возвращает объект Task. Когда поток выполнения достигает await, вызывающий поток приостанавливается до тех пор, пока вызов не будет завершен. Запустив эту версию приложения, вы обнаружите, что сообщение Completed отображается перед сообщением Done with work! В случае графического приложения можно было бы продолжать работу с пользовательским интерфейсом одновременно с выполнением метода DoWorkAsync().

Класс SynchronizationContext и async/await

Тип SynchronizationContext формально определен как базовый класс, который предоставляет свободный от потоков контекст баз синхронизации. Хотя такое первоначальное определение не особо информативно, в официальной документации указаны следующие сведения.

Цель модели синхронизации, реализуемой классом SynchronizationContext, заключается в том, чтобы позволить внутренним асинхронным/синхронным операциям общеязыковой исполняющей среды вести себя надлежащим образом с различными моделями синхронизации.

1 ... 292 293 294 295 296 297 298 299 300 ... 642
На этой странице вы можете бесплатно читать книгу Язык программирования C#9 и платформа .NET5 - Троелсен Эндрю бесплатно.
Похожие на Язык программирования C#9 и платформа .NET5 - Троелсен Эндрю книги

Оставить комментарий