Создание асинхронного метода в .NET 4.0, который можно использовать с «await» в .NET 4.5 - PullRequest
41 голосов
/ 06 марта 2012

У меня есть проект .NET, который использует C # в .NET 4.0 и VS2010.

Я хотел бы добавить некоторые асинхронные перегрузки в мою библиотеку, чтобы упростить выполнение асинхронного программирования для пользователей в .NET4.5 с ключевым словом await.Прямо сейчас перегруженные методы не асинхронны.Также я не хочу использовать какие-либо асинхронные методы самостоятельно, просто создаю новые и делаю их доступными.

Возможно ли создание асинхронных методов в .NET 4.0 и VS2010, и если да, то что должно делать .NET 4.0 асинхроннокак выглядит метод?

Поскольку я использую VS2010, у меня нет доступа к ключевому слову "async", так что же должно произойти, чтобы эмулировать это поведение в .NET 4.0?Например, нужно ли возвращать какой-либо конкретный тип, и должен ли какой-либо код происходить внутри метода, чтобы сделать асинхронный код, который он вызывает, асинхронным?

Ответы [ 3 ]

32 голосов
/ 06 марта 2012

Как уже говорили другие, вы начинаете с метода return Task или Task<TResult>. Этого достаточно для await его результата в .NET 4.5.

Чтобы ваш метод как можно лучше подходил к будущему асинхронному коду, следуйте указаниям в документе Асинхронный шаблон на основе задач (также доступен в MSDN ). Он предоставляет соглашения об именах и рекомендации по параметрам, например, для поддержки отмены.

Для реализации вашего метода у вас есть несколько вариантов:

  • Если у вас есть существующие IAsyncResult асинхронные методы, используйте Task.Factory.FromAsync.
  • Если у вас есть другая асинхронная система, используйте TaskCompletionSource<TResult>.
9 голосов
/ 06 марта 2012

Самый простой способ сделать это - вернуть Task или Task<T>.Этого будет достаточно.

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

Я также рекомендую придерживаться обычного шаблона их именования, например, AbcAsync (суффикс "Async").Ваши абоненты не заметят никакой разницы с асинхронным методом, созданным в C # 5 (потому что его нет).

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

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

3 голосов
/ 06 марта 2012

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

Выполнение Задачи асинхронно - другая история.Если у вас есть доступ к ключевому слову async и API, вы можете просто основывать свой метод на асинхронных вызовах других, уже предоставленных асинхронных методов.Но в этом случае вам придется вручную создавать свои асинхронные задачи.

Возможно, есть лучшие способы сделать это, но самый элегантный способ, который я вижу (и использовал), это использовать System.Threading.Tasks.TaskCompletionSource дляДля создания задачи используйте модель асинхронных методов Begin / End, чтобы выполнить все, что вам нужно.Затем, когда у вас есть результат, опубликуйте его в ранее созданном экземпляре Task, используя ваш источник завершения.

Он, безусловно, будет асинхронным, но не таким причудливым, как в следующем выпуске.

Отказ от ответственности: Я далеко не эксперт по этому вопросу.Только что провел несколько экспериментов.

...