Ожидаемый и ожидающий В C # 5.0 Асинхронный

Task or Task<tresult> object is awaitable, so we can use await key on those whose return value is Task or Task<tresult>. Task or Task<tresult> are the most frequently-used awaitable object.

Мы также можем определить наш собственный ожидаемый объект. Объект должен иметь квалификацию ниже.

  1. It has a GetAwaiter() method (instance method or extension method);
  2. Its GetAwaiter() method returns an awaiter. An object is an awaiter if:
    • It implements INotifyCompletion or ICriticalNotifyCompletion interface;
    • It has an IsCompleted, which has a getter and returns a Boolean;
    • it has a GetResult() method, which returns void, or a result.

Мой вопрос в том, почему Microsoft не предоставляла интерфейс для ограничения этих ожидаемых объектов? Текущий метод для реализации ожидаемого объекта немного сложнее.

10
добавлено
Просмотры: 1
de
Вы спрашиваете, почему GetAwaiter - это соглашение, а не метод интерфейса ITask? Microsoft ответила на этот вопрос где-то ... Хотел бы я вспомнить, где.
добавлено автор Cory Nelson, источник

2 ответы

It is best answered in Lucian Wischik's blog post Why must async methods return Task?

В целом (и я не занимаюсь правосудием в блоге, вы должны его прочитать), проблема в том, что Task уже существует, поэтому введение интерфейса означало бы

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

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

9
добавлено
Задача @PanagiotisKanavos равна IAsyncOperation, но операции async в C# по-прежнему возвращают задачу. Они используют метаданные для компиляции для преодоления различий. Я не понимаю на нем 100%, но я так понимаю, поэтому теоретически это означает, что вы правы, и вы ошибаетесь;)
добавлено автор Robert MacLean, источник
@PanagiotisKanavos Согласен, WinRT не имеет понятия задач - это функция .NET. Компилятор преобразует материал .NET в элементы WinRT с использованием проецирования. .NET также может ожидать все, что реализует GetAwaiter (см. Ссылку, которую я опубликовал)
добавлено автор Robert MacLean, источник
Фактически, они сделали это изменение в Windows RT, где асинхронные операции возвращают объекты IAsyncOperation, чтобы разместить языки не.NET. Теперь задачи используются для обертывания объектов IAsyncOperation
добавлено автор Panagiotis Kanavos, источник
У WinRT нет понятия задач. На самом деле, даже в C# вы можете вызвать await для операции, в которой не возвращает taks, поскольку возвращает объект с помощью метода GetAwaiter. Задачи в WinRT - это обертка, когда вам нужно работать с самим возвратным значением
добавлено автор Panagiotis Kanavos, источник
Ты нашел это! Потрясающие.
добавлено автор Cory Nelson, источник

Это соответствует тому, что они сделали для ключевого слова foreach (см. Раздел 8.8.4 раздела Спецификация языка C# " Оператор foreach ").

В принципе, это утка-типизация; если тип реализует метод MoveNext и свойство Current , это все, что необходимо для компилятора C#, чтобы знать, как итерации через последовательность, открытую объектом.

Это также относится к инициализаторам коллекции (см. Раздел 7.6.10.3 спецификации языка C# «Инициализаторы коллекции»); единственным требованием является то, что тип реализует System.Collections .Enumerable и используйте метод Добавить .

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

4
добавлено