Задача <T> vs Асинхронные делегаты в С#?

У меня есть этот простой метод:

static int Work (string s) { return s.Length; }

Я мог бы запустить его с помощью:

Task<string> task = Task.Factory.StartNew<int> (() => Work ("lalala") );
...
int result = task.Result;

Или с этим:

Func<string, int> method = Work;
IAsyncResult myIasync= method.BeginInvoke ("lalala", null, null);
...
int result = method.EndInvoke (myIasync);
  • Они используют поток threadpool.
  • Оба ждут завершения выполнения (при чтении значения)
  • Оба отзывают любое исключение для вызывающего.

Когда я должен использовать каждый?

Ответ 1

Вторая форма, используя IAsyncResult, значительно старше и намного менее мощна. Task<T> был введен в .NET 4 и является предпочтительным способом представления асинхронных операций. Это гораздо проще в использовании, особенно в С# 5, который поддерживает "асинхронные функции", где вы можете ожидать задачи (или другую асинхронную операцию) неблокирующим способом.

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

Если вы можете использовать С# 5 (либо с .NET 4.5, либо с .NET 4 плюс пакет асинхронного таргетинга), это значительно упростит вашу жизнь, когда дело доходит до управления асинхронными операциями. Это путь вперед:)

Ответ 2

Задача более элегантная и была введена совсем недавно (.Net 4), поэтому, если она соответствует вашим потребностям, я бы пошел с этим.