Общие сведения о поддержке асинхронного выполнения

C# 5 представил два ключевое слово для упрощения асинхронной программы: асинхронного и ожидаемого. Эти ключевое слово позволяют писать простой код, который использует библиотеку параллельных задач для выполнения длительных операций (например, сетевого доступа) в другом потоке и легко получить доступ к результатам при завершении. Последние версии Xamarin.iOS и Xamarin.Android поддерживают асинхронные и ожидаемые версии. В этом документе приведены объяснения и пример использования нового синтаксиса с Xamarin.

Поддержка Асинхронного приложения Xamarin основана на фундаменте Mono 3.0 и обновляет профиль API от того, что она является мобильной версией Silverlight, чтобы быть мобильной версией .NET 4.5.

Обзор

В этом документе представлены новые асинхронные и ожидающие ключевое слово, а затем приведены простые примеры реализации асинхронных методов в Xamarin.iOS и Xamarin.Android.

Дополнительные сведения о новых асинхронных функциях C# 5 (включая множество примеров и различных сценариев использования) см. в статье асинхронное программирование.

Пример приложения выполняет простой асинхронный веб-запрос (без блокировки основного потока), а затем обновляет пользовательский интерфейс с скачанным html-кодом и числом символов.

The sample application makes a simple asynchronous web request without blocking the main thread then updates the UI with the downloaded html and character count

Поддержка асинхронной поддержки Xamarin основана на фундаменте Mono 3.0 и обновляет профиль API от того, что является мобильной версией Silverlight, чтобы быть мобильной версией .NET 4.5.

Требования

Для функций C# 5 требуется Mono 3.0, включенный в Xamarin.iOS 6.4 и Xamarin.Android 4.8. Вам будет предложено обновить mono, Xamarin.iOS, Xamarin.Android и Xamarin.Mac, чтобы воспользоваться им.

Использование асинхронного & await

async и await являются новыми функциями языка C#, которые работают в сочетании с библиотекой параллельных задач, чтобы упростить написание потокового кода для выполнения длительных задач, не блокируя основной поток приложения.

async

Объявление

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

Метод, помеченный как async минимум одним выражением или оператором await. await Если операторы отсутствуют в методе, он будет выполняться синхронно (так же, как если бы не было async модификатора). Это также приведет к предупреждению компилятора (но не ошибке).

Типы возвращаемых данных

Асинхронный метод должен возвращать TaskTask<TResult> или void.

Укажите возвращаемый тип, Task если метод не возвращает другое значение.

Укажите Task<TResult> , требуется ли метод возвращать значение, где TResult возвращается тип (например int, например).

Возвращаемый void тип используется главным образом для обработчиков событий, которые требуют его. Код, вызывающий асинхронные методы void-returning, не await могут получить результат.

Параметры

Асинхронные методы не могут объявлять ref или out параметры.

await

Оператор await можно применить к задаче внутри метода, помеченного как асинхронный. Это приводит к остановке выполнения метода в этот момент и ожидает завершения задачи.

Использование await не блокирует поток вызывающего объекта— скорее элемент управления возвращается вызывающему объекту. Это означает, что вызывающий поток не заблокирован, поэтому, например, поток пользовательского интерфейса не будет заблокирован при ожидании задачи.

По завершении задачи метод возобновляет выполнение в той же точке кода. Это включает возврат к область пробной область блока try-catch-finally (если он присутствует). ожидание нельзя использовать в блоке catch или, наконец, .

Дополнительные сведения о ожидании.

Обработка исключений.

Исключения, возникающие внутри асинхронного метода, хранятся в задаче и создаются при выполнении задачи await. Эти исключения можно поймать и обработать в блоке try-catch.

Отмена

Асинхронные методы, которые занимают много времени, должны поддерживать отмену. Как правило, отмена вызывается следующим образом:

  • CancellationTokenSource Создается объект.
  • Экземпляр CancellationTokenSource.Token передается в отменяемый асинхронный метод.
  • Отмена запрашивается путем CancellationTokenSource.Cancel вызова метода.

Затем задача отменяет себя и подтверждает отмену.

Дополнительные сведения об отмене см. в разделе Настройка асинхронного приложения (C#).

Пример

Скачайте пример решения Xamarin (для iOS и Android), чтобы просмотреть рабочий пример asyncawait и в мобильных приложениях. Пример кода подробно рассматривается в этом разделе.

Написание асинхронного метода

В следующем методе показано, как кодировать async метод с awaitпомощью задачи ed:

public async Task<int> DownloadHomepage()
{
    var httpClient = new HttpClient(); // Xamarin supports HttpClient!

    Task<string> contentsTask = httpClient.GetStringAsync("https://visualstudio.microsoft.com/xamarin"); // async method!

    // await! control returns to the caller and the task continues to run on another thread
    string contents = await contentsTask;

    ResultEditText.Text += "DownloadHomepage method continues after async call. . . . .\n";

    // After contentTask completes, you can calculate the length of the string.
    int exampleInt = contents.Length;

    ResultEditText.Text += "Downloaded the html and found out the length.\n\n\n";

    ResultEditText.Text += contents; // just dump the entire HTML

    return exampleInt; // Task<TResult> returns an object of type TResult, in this case int
}

Обратите внимание на следующие моменты.

  • Объявление метода включает async ключевое слово.
  • Возвращаемый тип позволяет Task<int> вызывать код, чтобы получить доступ к int значению, вычисляемого в этом методе.
  • Оператор return — это return exampleInt; целочисленный объект— тот факт, что возвращаемый Task<int> метод является частью улучшения языка.

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

Этот обработчик событий нажатия кнопки можно найти в примере приложения Android для вызова метода, описанного выше:

GetButton.Click += async (sender, e) => {

    Task<int> sizeTask = DownloadHomepage();

    ResultTextView.Text = "loading...";
    ResultEditText.Text = "loading...\n";

    // await! control returns to the caller
    var intResult = await sizeTask;

    // when the Task<int> returns, the value is available and we can display on the UI
    ResultTextView.Text = "Length: " + intResult ;
    // "returns" void, since it's an event handler
};

Примечания:

  • Анонимный делегат имеет асинхронный ключевое слово префикс.
  • Асинхронный метод DownloadHomepage возвращает int> task<, хранящийся в переменной sizeTask.
  • Код ожидается в переменной sizeTask. Это расположение, которое метод приостановлен и элемент управления возвращается в вызывающий код, пока асинхронная задача не завершится в собственном потоке.
  • Выполнение не приостанавливается при создании задачи в первой строке метода, несмотря на то, что задача создается там. Ожидание ключевое слово обозначает расположение приостановки выполнения.
  • После завершения асинхронной задачи intResult устанавливается и выполнение продолжается в исходном потоке из строки ожидания.

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

В примере приложения iOS пример написан немного по-другому, чтобы продемонстрировать альтернативный подход. Вместо использования анонимного делегата в этом примере объявляется async обработчик событий, назначенный как обычный обработчик событий:

GetButton.TouchUpInside += HandleTouchUpInside;

Затем метод обработчика событий определяется следующим образом:

async void HandleTouchUpInside (object sender, EventArgs e)
{
    ResultLabel.Text = "loading...";
    ResultTextView.Text = "loading...\n";

    // await! control returns to the caller
    var intResult = await DownloadHomepage();

    // when the Task<int> returns, the value is available and we can display on the UI
    ResultLabel.Text = "Length: " + intResult ;
}

Некоторые важные моменты:

  • Метод помечается как async возвращающий void . Обычно это делается только для обработчиков событий (в противном случае вы вернете или TaskTask<TResult> ).
  • Ключевое слово await метода DownloadHomepage напрямую назначает переменную (intResultв отличие от предыдущего примера, где мы использовали промежуточную Task<int> переменную для ссылки на задачу. Это расположение, где элемент управления возвращается вызывающей стороне до завершения асинхронного метода в другом потоке.
  • Когда асинхронный метод завершается и возвращается, выполнение возобновляется при await возврате целочисленного результата, а затем отрисовывается в мини-приложении пользовательского интерфейса.

Итоги

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

В этом документе представлен обзор новых языковых ключевое слово и примеров для Xamarin.iOS и Xamarin.Android.