Вопрос

Microsoft объявил Visual Studio Async CTP сегодня (28 октября 2010 г.), который вводит async а также await Ключевые слова в C # / VB для исполнения асинхронного метода.

Сначала я подумал, что компилятор переводит ключевые слова в создание нити, но в соответствии с белая бумага И Андерс Хейлсберг PDC презентация (в 31:00) асинхронная операция происходит полностью на главной ните.

Как я могу выполнить операцию, выполненную параллельно в том же ниве? Как это технически возможно и к какой функции фактически переведена в IL?

Это было полезно?

Решение

Это работает аналогично yield return Ключевое слово в C # 2.0.

Асинхронный метод на самом деле не является обычным последовательным методом. Он скомпилирован в состояние состояния (объект) с некоторым состоянием (локальные переменные превращаются в поля объекта). Каждый блок кода между двумя использованием await это один «шаг» государственной машины.

Это означает, что когда начнет метод, он просто запускает первый шаг, а затем возвращается состояние машины и расписание некоторые работы, которые необходимо выполнить - когда работа выполнена, она будет запускать следующий шаг состояния. Например, этот код:

async Task Demo() { 
  var v1 = foo();
  var v2 = await bar();
  more(v1, v2);
}

Будет переведен на что-то вроде:

class _Demo {
  int _v1, _v2;
  int _state = 0; 
  Task<int> _await1;
  public void Step() {
    switch(this._state) {
    case 0: 
      this._v1 = foo();
      this._await1 = bar();
      // When the async operation completes, it will call this method
      this._state = 1;
      op.SetContinuation(Step);
    case 1:
      this._v2 = this._await1.Result; // Get the result of the operation
      more(this._v1, this._v2);
  }
}

Важная часть заключается в том, что она просто использует SetContinuation Метод Укажите, что когда операция завершается, она должна позвонить Step метод снова (и метод знает, что он должен запускать второй бит исходного кода, используя _state поле). Вы можете легко представить, что SetContinuation было бы что-то вроде btn.Click += Step, что будет работать полностью на одном потоке.

Модель асинхронного программирования в C # очень близко к F # асинхронным рабочим процессам (на самом деле, по сути то же самое, кроме некоторых технических деталей), а также написание реактивных однопоточных приложений GUI, используя async Это довольно интересная область - по крайней мере, я так думаю - посмотреть, например, эта статья (Может быть, я должен написать версию C # сейчас :-)).

Перевод похож на итераторы (и yield return) И на самом деле, можно было использовать итераторы для реализации асинхронного программирования в C # ранее. я написал статья о том Данное назад - и я думаю, что это все равно может дать вам некоторое понимание того, как работает перевод.

Другие советы

Как я могу выполнить операцию, выполненную параллельно в том же ниве?

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

У меня есть целый ряд статей в моем блоге о том, как все это работает; Один, непосредственный герман к этому вопросу, вероятно, будет идти в четверг на следующей неделе. Смотреть

http://blogs.msdn.com/b/ericlippert/archive/tags/async/

для деталей.

Как я понимаю, что async а также await Ключевые слова делают в том, что каждый раз async Метод использует await Ключевое слово, компилятор превратит оставшуюся часть метода в продолжение, которое запланировано, когда операция ASYNC завершена. Это позволяет async Методы, чтобы вернуться к абонеру немедленно и возобновить работу при выполнении асинхронизации.

Согласно доступным документам, к нему много деталей, но если я не ошибаюсь, это суть его.

Когда я вижу, что целью асинковых методов - не запускать много кода параллельно, но чтобы порешить асинхронные методы в ряд небольших кусков, которые можно назвать по мере необходимости. Ключевым моментом является то, что компилятор будет обрабатывать всю сложную проводку обратных вызовов, используя задачи / продолжения. Это не только уменьшает сложность, но позволяет писать Async, чтобы быть написанным более или менее, как традиционный синхронный код.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top